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 1862 2011-02-20 17:22:55Z 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");
56 printf("# commands: h, c, o, l, x, i, r, a, s, u\r\n");
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;
1862 kakl 140 signed int16 ta, to1, to2, tTouch, told;
1720 kakl 141 int8 tLSB,tMSB; // Temperatures from TouchMemory
1280 kakl 142 int8 safety_counter;
1720 kakl 143 int1 repeat; // Status flags
144 int1 automatic;
1274 kakl 145  
1285 kakl 146 output_high(DOME); // Close Dome
1274 kakl 147 output_low(HEATING); // Heating off
148  
149 delay_ms(1000);
150 restart_wdt();
1284 kakl 151  
1285 kakl 152 seq=0; // Variables initiation
153 heat=0;
154 open=0;
1291 kakl 155 repeat=TRUE;
1720 kakl 156 automatic=FALSE;
1289 kakl 157  
1284 kakl 158 welcome();
1285 kakl 159  
1274 kakl 160 tempa=ReadTemp(SA, RAM_Tamb); // Dummy read
161 temp=ReadTemp(SA, RAM_Tobj1);
1720 kakl 162 touch_present(); //Issues a reset of Touch Memory device
163 touch_write_byte(0xCC);
164 touch_write_byte(0x44);
1274 kakl 165  
1286 kakl 166 delay_ms(1000);
1280 kakl 167 //---WDT
1274 kakl 168 restart_wdt();
1862 kakl 169  
1284 kakl 170 while(TRUE) // Main Loop
1274 kakl 171 {
1284 kakl 172 safety_counter=SAFETY_COUNT; // Heating and Dome Count Down
1278 kakl 173 do
1274 kakl 174 {
1280 kakl 175 if (safety_counter<SAFETY_COUNT) safety_counter++;
1274 kakl 176  
1280 kakl 177 delay(RESPONSE_DELAY);
178  
179 if (safety_counter>=SAFETY_COUNT)
180 {
1862 kakl 181 if (heat>0) { output_high(HEATING); } else { output_low(HEATING); }
182  
1288 kakl 183 if (heat>0) heat--;
1280 kakl 184 if (open>0) open--;
185  
186 safety_counter=0;
187 //---WDT
188 restart_wdt();
189 }
1288 kakl 190 } while (!kbhit()&&!repeat);
1285 kakl 191  
1280 kakl 192 //---WDT
193 restart_wdt();
1284 kakl 194 { // Retrieve command
1288 kakl 195 char ch='k';
1278 kakl 196  
1288 kakl 197 if(kbhit()) ch=getc();
1278 kakl 198  
1274 kakl 199 switch (ch)
200 {
201 case 'h':
1280 kakl 202 heat=MAXHEAT; // Need heating
1720 kakl 203 automatic=FALSE;
1274 kakl 204 break;
1278 kakl 205  
1274 kakl 206 case 'c':
1280 kakl 207 heat=0; // Need colder
1720 kakl 208 automatic=FALSE;
1274 kakl 209 break;
1278 kakl 210  
1274 kakl 211 case 'o':
212 open=MAXOPEN; // Open the dome
1720 kakl 213 automatic=FALSE;
1274 kakl 214 break;
1278 kakl 215  
1284 kakl 216 case 'x':
217 open=MAXOPEN; // Open the dome
218 heat=MAXHEAT; // Need heating
1720 kakl 219 automatic=FALSE;
1284 kakl 220 break;
221  
1274 kakl 222 case 'l':
223 open=0; // Lock the dome
1720 kakl 224 automatic=FALSE;
1274 kakl 225 break;
1284 kakl 226  
227 case 'i':
1287 kakl 228 if (open==0) welcome(); // Information about version, etc...
229 break; // Only when dome is closed
1288 kakl 230  
231 case 'r':
1292 kakl 232 repeat=TRUE; // Repeated measure mode
1720 kakl 233 automatic=FALSE;
1288 kakl 234 break;
235  
236 case 's':
237 repeat=FALSE; // Single measure mode
1720 kakl 238 automatic=FALSE;
1288 kakl 239 break;
1293 kakl 240  
1720 kakl 241 case 'a':
242 repeat=TRUE; // Automatic mode
243 automatic=TRUE;
244 break;
245  
1293 kakl 246 case 'u':
1300 kakl 247 reset_cpu(); // Update firmware
1274 kakl 248 }
249 }
1288 kakl 250 CREN=0; CREN=1; // Reinitialise USART
1274 kakl 251  
1280 kakl 252 seq++; // Increment the number of measurement
1274 kakl 253  
254 tempa=ReadTemp(SA, RAM_Tamb); // Read temperatures from sensor
1720 kakl 255 ta=tempa*2-27315; // °K -> °C
256  
1274 kakl 257 temp=ReadTemp(SA, RAM_Tobj1);
1720 kakl 258 if (temp>0x48E1) {to1=-27315;} else {to1=temp*2-27315;}
259 temp=ReadTemp(SA, RAM_Tobj2);
260 if (temp>0x48E1) {to2=-27315;} else {to2=temp*2-27315;}
1274 kakl 261  
1720 kakl 262 touch_present(); //Issues a reset of Touch Memory device
263 touch_write_byte(0xCC);
264 touch_write_byte(0x44);
265  
266 //---WDT
267 restart_wdt();
268 delay(MEASURE_DELAY); // Delay to a next measurement
1274 kakl 269  
1720 kakl 270 {
271 int8 SN[10];
272 int8 n;
273  
274 touch_present(); //Issues a reset and returns true if the touch device is there.
275 touch_write_byte(0xCC);
276 touch_write_byte(0xBE);
277 for(n=0;n<9;n++) SN[n]=touch_read_byte();
278 tLSB=SN[0];
279 tMSB=SN[1];
280 if ((SN[8]==TM_check_CRC(SN,8))&&(SN[7]==0x10)) // Check CRC and family code to prevent O's error
281 {
282 tTouch=make16(tMSB,tLSB);
283 tTouch=tTouch*6+tTouch/4; // 1bit = 0,0625gradC recalculate to 1/100gradC
284 }
285 else
286 {
287 tTouch=-27315;
288 }
289 }
290  
291 if(automatic) // Solve automatic mode
292 {
1862 kakl 293 if(((ta<400)||(ta<(tTouch+400)))&&(ta<2000)&&(ta<told)) heat=1; // Need heating
294 told=ta;
295 if((abs(to1-to2)<100)&&(tTouch>to1)&&(abs(tTouch-to1)>800))
296 open=1; // Open the dome
1720 kakl 297 }
298  
1274 kakl 299 { // printf
1284 kakl 300 char output[8]; // Output buffer
301 int8 j; // String pointer
1293 kakl 302 int8 check=0; // Checksum is calculated between '$' and '*'
1278 kakl 303  
1282 kakl 304 delay(SEND_DELAY);
1293 kakl 305 putc('$');
306 delay(SEND_DELAY);
1720 kakl 307 sprintf(output,"M%s \0",VER);
1293 kakl 308 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1720 kakl 309 sprintf(output,"%Lu \0", seq);
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", ta);
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", to1);
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", to2);
1293 kakl 316 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1720 kakl 317 sprintf(output,"%Ld \0",tTouch);
1293 kakl 318 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1720 kakl 319 sprintf(output,"%u \0", heat);
320 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
321 sprintf(output,"%u \0", open);
322 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
323 sprintf(output,"*%X\r\n\0", check);
1282 kakl 324 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j++]); }
1293 kakl 325 delay(SEND_DELAY);
1274 kakl 326 }
1720 kakl 327  
1280 kakl 328 //---WDT
329 restart_wdt();
1274 kakl 330 }
331 }
1298 kakl 332  
333  
1300 kakl 334 #include "dbloader.c" // Space reservation for the BootLoader