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