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