Rev Author Line No. Line
1274 kakl 1 /**** IR Mrakomer 4 ****/
1720 kakl 2 #define VERSION "4.1"
1277 kakl 3 #define ID "$Id: irmrak4.c 1720 2010-12-10 20:47:52Z 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>
13  
1289 kakl 14 #CASE // Case sensitive compiler
15  
1280 kakl 16 #define MAXHEAT 20 // Number of cycles for heating
17 #define MAXOPEN 20 // Number of cycles for dome open
1287 kakl 18 #define MEASURE_DELAY 6000 // Delay to a next measurement
1280 kakl 19 #define RESPONSE_DELAY 100 // Reaction time after receiving a command
1287 kakl 20 #define SAFETY_COUNT 90 // Time of one emergency cycle
1280 kakl 21 #define SEND_DELAY 50 // Time between two characters on RS232
1275 kakl 22  
1274 kakl 23 #define DOME PIN_B4 // Dome controll port
24 #define HEATING PIN_B3 // Heating for defrosting
25  
26  
1280 kakl 27 char VER[4]=VERSION; // Buffer for concatenate of a version string
1274 kakl 28  
1280 kakl 29 int8 heat; // Status variables
1274 kakl 30 int8 open;
31  
1284 kakl 32 inline void toggle_dome(void) // Wire exercise
1275 kakl 33 {
34 if (open>0)
1285 kakl 35 {output_toggle(DOME);} // Toggle = Open Dome
36 else
37 {output_high(DOME);} // Do not toggle = Close Dome
1275 kakl 38 }
1274 kakl 39  
1284 kakl 40 void delay(int16 cycles) // Wire exercise with delay
1274 kakl 41 {
1275 kakl 42 int16 i;
1278 kakl 43  
1275 kakl 44 for(i=0; i<cycles; i++) {toggle_dome(); delay_us(100);}
45 }
1274 kakl 46  
1284 kakl 47 void welcome(void) // Welcome message
48 {
1293 kakl 49 char REV[50]=ID; // Buffer for concatenate of a version string
50  
51 if (REV[strlen(REV)-1]=='$') REV[strlen(REV)-1]=0;
1720 kakl 52 printf("\r\n\r\n# Mrakomer %s (C) 2007 UST\n\r",VER); // Welcome message
53 printf("#%s\r\n",&REV[4]);
54 // printf("#\r\n");
55 printf("# commands: h, c, o, l, x, i, r, a, s, u\r\n");
56 // printf("# h_eat, c_old, o_pen, l_ock, x_open, ");
57 // printf("i_nfo, r_epeat, a_uto, s_single, u_pdate\r\n");
58 // printf("#\r\n");
59 printf("# ver seq in[1/100 C] sky[1/100 C] sky[1/100 C] ");
60 printf("out[1/100 C] heat[s] dome[s] check\r\n\r\n");
61  
1303 kakl 62 //---WDT
63 restart_wdt();
1284 kakl 64 }
1274 kakl 65  
66  
1284 kakl 67 #include "smb.c" // System Management Bus driver
1720 kakl 68 #include "TOUCH.C"
1274 kakl 69  
1284 kakl 70  
1293 kakl 71 // Read sensor's RAM
1280 kakl 72 // Returns temperature in °K
1281 kakl 73 int16 ReadTemp(int8 addr, int8 select)
1274 kakl 74 {
75 unsigned char arr[6]; // Buffer for the sent bytes
76 int8 crc; // Readed CRC
77 int16 temp; // Readed temperature
78  
1275 kakl 79 addr<<=1;
80  
1284 kakl 81 SMB_STOP_bit(); //If slave send NACK stop comunication
82 SMB_START_bit(); //Start condition
1275 kakl 83 SMB_TX_byte(addr);
84 SMB_TX_byte(RAM_Access|select);
1284 kakl 85 SMB_START_bit(); //Repeated Start condition
1275 kakl 86 SMB_TX_byte(addr);
1284 kakl 87 arr[2]=SMB_RX_byte(ACK); //Read low data,master must send ACK
88 arr[1]=SMB_RX_byte(ACK); //Read high data,master must send ACK
1289 kakl 89 temp=make16(arr[1],arr[2]);
1284 kakl 90 crc=SMB_RX_byte(NACK); //Read PEC byte, master must send NACK
91 SMB_STOP_bit(); //Stop condition
1274 kakl 92  
93 arr[5]=addr;
94 arr[4]=RAM_Access|select;
95 arr[3]=addr;
96 arr[0]=0;
97 if (crc != PEC_calculation(arr)) temp=0; // Calculate and check CRC
98  
99 return temp;
100 }
101  
1720 kakl 102 // compute CRC
103 // *sn - pointer to the byte array
104 // num - length of array
105 inline int8 TM_check_CRC(unsigned int8 *sn, unsigned int8 num)
106 {
107 // CRC table
108 const int8 TouchCRC[256]= {
109 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
110 157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
111 35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
112 190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
113 70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
114 219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
115 101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
116 248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
117 140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205,
118 17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,
119 175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,
120 50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
121 202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
122 87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
123 233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
124 116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53};
1298 kakl 125  
1720 kakl 126 int8 CRC;
127 int8 i;
128  
129 CRC=0;
130 for(i=0;i<num;i++) CRC=TouchCRC[CRC ^ *(sn+i)];
131 return(CRC);
132 }
133  
134  
1298 kakl 135 /*-------------------------------- MAIN --------------------------------------*/
1300 kakl 136 void main()
1274 kakl 137 {
1280 kakl 138 unsigned int16 seq, temp, tempa;
1720 kakl 139 signed int16 ta, to1, to2, tTouch;
140 int8 tLSB,tMSB; // Temperatures from TouchMemory
1280 kakl 141 int8 safety_counter;
1720 kakl 142 int1 repeat; // Status flags
143 int1 automatic;
1274 kakl 144  
1285 kakl 145 output_high(DOME); // Close Dome
1274 kakl 146 output_low(HEATING); // Heating off
147  
148 delay_ms(1000);
149 restart_wdt();
1284 kakl 150  
1285 kakl 151 seq=0; // Variables initiation
152 heat=0;
153 open=0;
1291 kakl 154 repeat=TRUE;
1720 kakl 155 automatic=FALSE;
1289 kakl 156  
1284 kakl 157 welcome();
1285 kakl 158  
1274 kakl 159 tempa=ReadTemp(SA, RAM_Tamb); // Dummy read
160 temp=ReadTemp(SA, RAM_Tobj1);
1720 kakl 161 touch_present(); //Issues a reset of Touch Memory device
162 touch_write_byte(0xCC);
163 touch_write_byte(0x44);
1274 kakl 164  
1286 kakl 165 delay_ms(1000);
1280 kakl 166 //---WDT
1274 kakl 167 restart_wdt();
168  
1284 kakl 169 while(TRUE) // Main Loop
1274 kakl 170 {
1284 kakl 171 safety_counter=SAFETY_COUNT; // Heating and Dome Count Down
1278 kakl 172 do
1274 kakl 173 {
1280 kakl 174 if (safety_counter<SAFETY_COUNT) safety_counter++;
1274 kakl 175  
1280 kakl 176 delay(RESPONSE_DELAY);
177  
178 if (safety_counter>=SAFETY_COUNT)
179 {
1288 kakl 180 if (heat>0) heat--;
1280 kakl 181 if (open>0) open--;
182  
1290 kakl 183 if (heat>0) { output_high(HEATING); } else { output_low(HEATING); }
184  
1280 kakl 185 safety_counter=0;
186 //---WDT
187 restart_wdt();
188 }
1288 kakl 189 } while (!kbhit()&&!repeat);
1285 kakl 190  
1280 kakl 191 //---WDT
192 restart_wdt();
1284 kakl 193 { // Retrieve command
1288 kakl 194 char ch='k';
1278 kakl 195  
1288 kakl 196 if(kbhit()) ch=getc();
1278 kakl 197  
1274 kakl 198 switch (ch)
199 {
200 case 'h':
1280 kakl 201 heat=MAXHEAT; // Need heating
1720 kakl 202 automatic=FALSE;
1274 kakl 203 break;
1278 kakl 204  
1274 kakl 205 case 'c':
1280 kakl 206 heat=0; // Need colder
1720 kakl 207 automatic=FALSE;
1274 kakl 208 break;
1278 kakl 209  
1274 kakl 210 case 'o':
211 open=MAXOPEN; // Open the dome
1720 kakl 212 automatic=FALSE;
1274 kakl 213 break;
1278 kakl 214  
1284 kakl 215 case 'x':
216 open=MAXOPEN; // Open the dome
217 heat=MAXHEAT; // Need heating
1720 kakl 218 automatic=FALSE;
1284 kakl 219 break;
220  
1274 kakl 221 case 'l':
222 open=0; // Lock the dome
1720 kakl 223 automatic=FALSE;
1274 kakl 224 break;
1284 kakl 225  
226 case 'i':
1287 kakl 227 if (open==0) welcome(); // Information about version, etc...
228 break; // Only when dome is closed
1288 kakl 229  
230 case 'r':
1292 kakl 231 repeat=TRUE; // Repeated measure mode
1720 kakl 232 automatic=FALSE;
1288 kakl 233 break;
234  
235 case 's':
236 repeat=FALSE; // Single measure mode
1720 kakl 237 automatic=FALSE;
1288 kakl 238 break;
1293 kakl 239  
1720 kakl 240 case 'a':
241 repeat=TRUE; // Automatic mode
242 automatic=TRUE;
243 break;
244  
1293 kakl 245 case 'u':
1300 kakl 246 reset_cpu(); // Update firmware
1274 kakl 247 }
248 }
1288 kakl 249 CREN=0; CREN=1; // Reinitialise USART
1274 kakl 250  
1280 kakl 251 seq++; // Increment the number of measurement
1274 kakl 252  
253 tempa=ReadTemp(SA, RAM_Tamb); // Read temperatures from sensor
1720 kakl 254 ta=tempa*2-27315; // °K -> °C
255  
1274 kakl 256 temp=ReadTemp(SA, RAM_Tobj1);
1720 kakl 257 if (temp>0x48E1) {to1=-27315;} else {to1=temp*2-27315;}
258 temp=ReadTemp(SA, RAM_Tobj2);
259 if (temp>0x48E1) {to2=-27315;} else {to2=temp*2-27315;}
1274 kakl 260  
1720 kakl 261 touch_present(); //Issues a reset of Touch Memory device
262 touch_write_byte(0xCC);
263 touch_write_byte(0x44);
264  
265 //---WDT
266 restart_wdt();
267 delay(MEASURE_DELAY); // Delay to a next measurement
1274 kakl 268  
1720 kakl 269 {
270 int8 SN[10];
271 int8 n;
272  
273 touch_present(); //Issues a reset and returns true if the touch device is there.
274 touch_write_byte(0xCC);
275 touch_write_byte(0xBE);
276 for(n=0;n<9;n++) SN[n]=touch_read_byte();
277 tLSB=SN[0];
278 tMSB=SN[1];
279 if ((SN[8]==TM_check_CRC(SN,8))&&(SN[7]==0x10)) // Check CRC and family code to prevent O's error
280 {
281 tTouch=make16(tMSB,tLSB);
282 tTouch=tTouch*6+tTouch/4; // 1bit = 0,0625gradC recalculate to 1/100gradC
283 }
284 else
285 {
286 tTouch=-27315;
287 }
288 }
289  
290 if(automatic) // Solve automatic mode
291 {
292 if(ta<1800) heat=MAXHEAT; // Need heating
293 if((abs(to1-to2)<80)&&(tTouch>to1)&&(abs(tTouch-to1)>1500))
294 open=MAXOPEN; // Open the dome
295 }
296  
1274 kakl 297 { // printf
1284 kakl 298 char output[8]; // Output buffer
299 int8 j; // String pointer
1293 kakl 300 int8 check=0; // Checksum is calculated between '$' and '*'
1278 kakl 301  
1282 kakl 302 delay(SEND_DELAY);
1293 kakl 303 putc('$');
304 delay(SEND_DELAY);
1720 kakl 305 sprintf(output,"M%s \0",VER);
1293 kakl 306 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1720 kakl 307 sprintf(output,"%Lu \0", seq);
1293 kakl 308 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1720 kakl 309 sprintf(output,"%Ld \0", ta);
1293 kakl 310 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1720 kakl 311 sprintf(output,"%Ld \0", to1);
1293 kakl 312 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1720 kakl 313 sprintf(output,"%Ld \0", to2);
1293 kakl 314 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1720 kakl 315 sprintf(output,"%Ld \0",tTouch);
1293 kakl 316 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1720 kakl 317 sprintf(output,"%u \0", heat);
318 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
319 sprintf(output,"%u \0", open);
320 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
321 sprintf(output,"*%X\r\n\0", check);
1282 kakl 322 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j++]); }
1293 kakl 323 delay(SEND_DELAY);
1274 kakl 324 }
1720 kakl 325  
1280 kakl 326 //---WDT
327 restart_wdt();
1274 kakl 328 }
329 }
1298 kakl 330  
331  
1300 kakl 332 #include "dbloader.c" // Space reservation for the BootLoader