Rev Author Line No. Line
1597 kakl 1 /**** IR Mrakomer 4 ****/
2 #define VERSION "4.1"
3 #define ID "$Id: irmrak4.c 1705 2010-12-05 19:24:34Z kakl $"
4  
5 #include "irmrak4.h"
6  
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  
14 #CASE // Case sensitive compiler
15  
16 #define MAXHEAT 20 // Number of cycles for heating
17 #define MAXOPEN 20 // Number of cycles for dome open
18 #define MEASURE_DELAY 6000 // Delay to a next measurement
19 #define RESPONSE_DELAY 100 // Reaction time after receiving a command
20 #define SAFETY_COUNT 90 // Time of one emergency cycle
21 #define SEND_DELAY 50 // Time between two characters on RS232
22  
23 #define DOME PIN_B4 // Dome controll port
24 #define HEATING PIN_B3 // Heating for defrosting
25  
26  
27 char VER[4]=VERSION; // Buffer for concatenate of a version string
28  
29 int8 heat; // Status variables
30 int8 open;
31  
32 inline void toggle_dome(void) // Wire exercise
33 {
34 if (open>0)
35 {output_toggle(DOME);} // Toggle = Open Dome
36 else
37 {output_high(DOME);} // Do not toggle = Close Dome
38 }
39  
40 void delay(int16 cycles) // Wire exercise with delay
41 {
42 int16 i;
43  
44 for(i=0; i<cycles; i++) {toggle_dome(); delay_us(100);}
45 }
46  
47 void welcome(void) // Welcome message
48 {
49 char REV[50]=ID; // Buffer for concatenate of a version string
50  
51 if (REV[strlen(REV)-1]=='$') REV[strlen(REV)-1]=0;
1705 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:\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");
1703 kakl 59 printf("# <ver> <sequence> <inside[1/100 C]> <sky[1/100 C]> <sky[1/100 C]> ");
1705 kakl 60 printf("<ambient[1/100 C]> <heating[s]> <dome[s]> <check>\r\n\r\n");
61  
1597 kakl 62 //---WDT
63 restart_wdt();
64 }
65  
66  
67 #include "smb.c" // System Management Bus driver
1705 kakl 68 #include "TOUCH.C"
1597 kakl 69  
70  
71 // Read sensor's RAM
72 // Returns temperature in °K
73 int16 ReadTemp(int8 addr, int8 select)
74 {
75 unsigned char arr[6]; // Buffer for the sent bytes
76 int8 crc; // Readed CRC
77 int16 temp; // Readed temperature
78  
79 addr<<=1;
80  
81 SMB_STOP_bit(); //If slave send NACK stop comunication
82 SMB_START_bit(); //Start condition
83 SMB_TX_byte(addr);
84 SMB_TX_byte(RAM_Access|select);
85 SMB_START_bit(); //Repeated Start condition
86 SMB_TX_byte(addr);
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
89 temp=make16(arr[1],arr[2]);
90 crc=SMB_RX_byte(NACK); //Read PEC byte, master must send NACK
91 SMB_STOP_bit(); //Stop condition
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  
1703 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};
1597 kakl 125  
1703 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  
1597 kakl 135 /*-------------------------------- MAIN --------------------------------------*/
136 void main()
137 {
138 unsigned int16 seq, temp, tempa;
1703 kakl 139 signed int16 ta, to1, to2, tTouch;
140 int8 tLSB,tMSB; // Temperatures from TouchMemory
1597 kakl 141 int8 safety_counter;
1705 kakl 142 int1 repeat; // Status flags
143 int1 automatic;
1597 kakl 144  
145 output_high(DOME); // Close Dome
146 output_low(HEATING); // Heating off
147  
148 delay_ms(1000);
149 restart_wdt();
150  
151 seq=0; // Variables initiation
152 heat=0;
153 open=0;
154 repeat=TRUE;
155  
156 welcome();
157  
158 tempa=ReadTemp(SA, RAM_Tamb); // Dummy read
159 temp=ReadTemp(SA, RAM_Tobj1);
1703 kakl 160 touch_present(); //Issues a reset of Touch Memory device
161 touch_write_byte(0xCC);
162 touch_write_byte(0x44);
1597 kakl 163  
164 delay_ms(1000);
165 //---WDT
166 restart_wdt();
167  
168 while(TRUE) // Main Loop
169 {
170 safety_counter=SAFETY_COUNT; // Heating and Dome Count Down
171 do
172 {
173 if (safety_counter<SAFETY_COUNT) safety_counter++;
174  
175 delay(RESPONSE_DELAY);
176  
177 if (safety_counter>=SAFETY_COUNT)
178 {
179 if (heat>0) heat--;
180 if (open>0) open--;
181  
182 if (heat>0) { output_high(HEATING); } else { output_low(HEATING); }
183  
184 safety_counter=0;
185 //---WDT
186 restart_wdt();
187 }
188 } while (!kbhit()&&!repeat);
189  
190 //---WDT
191 restart_wdt();
192 { // Retrieve command
193 char ch='k';
194  
195 if(kbhit()) ch=getc();
196  
197 switch (ch)
198 {
199 case 'h':
200 heat=MAXHEAT; // Need heating
1705 kakl 201 automatic=FALSE;
1597 kakl 202 break;
203  
204 case 'c':
205 heat=0; // Need colder
1705 kakl 206 automatic=FALSE;
1597 kakl 207 break;
208  
209 case 'o':
210 open=MAXOPEN; // Open the dome
1705 kakl 211 automatic=FALSE;
1597 kakl 212 break;
213  
214 case 'x':
215 open=MAXOPEN; // Open the dome
216 heat=MAXHEAT; // Need heating
1705 kakl 217 automatic=FALSE;
1597 kakl 218 break;
219  
220 case 'l':
221 open=0; // Lock the dome
1705 kakl 222 automatic=FALSE;
1597 kakl 223 break;
224  
225 case 'i':
226 if (open==0) welcome(); // Information about version, etc...
227 break; // Only when dome is closed
228  
229 case 'r':
230 repeat=TRUE; // Repeated measure mode
1705 kakl 231 automatic=FALSE;
1597 kakl 232 break;
233  
234 case 's':
235 repeat=FALSE; // Single measure mode
1705 kakl 236 automatic=FALSE;
1597 kakl 237 break;
238  
1705 kakl 239 case 'a':
240 repeat=TRUE; // Automatic mode
241 automatic=TRUE;
242 break;
243  
1597 kakl 244 case 'u':
245 reset_cpu(); // Update firmware
246 }
247 }
248 // while(kbhit()) getc(); // Flush USART buffer
249 CREN=0; CREN=1; // Reinitialise USART
250  
251 seq++; // Increment the number of measurement
252  
253 tempa=ReadTemp(SA, RAM_Tamb); // Read temperatures from sensor
254 ta=tempa*2-27315; // °K -> °C
255  
256 temp=ReadTemp(SA, RAM_Tobj1);
257 to1=temp*2-27315;
258 temp=ReadTemp(SA, RAM_Tobj2);
259 to2=temp*2-27315;
260  
1703 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
268  
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);
1705 kakl 282 tTouch=tTouch*6+tTouch/4; // 1bit = 0,0625gradC recalculate to 1/100gradC
1703 kakl 283 }
284 else
285 {
1705 kakl 286 tTouch=-27315;
1703 kakl 287 }
288 }
289  
1705 kakl 290 if(automatic) // Solve automatic mode
291 {
292 if(ta<1800) heat=MAXHEAT; // Need heating
293 if((abs(to1-to2)<200)&&(tTouch>to1)&&(abs(tTouch/4-to1)>500))
294 open=MAXOPEN; // Open the dome
295 }
296  
1597 kakl 297 { // printf
298 char output[8]; // Output buffer
299 int8 j; // String pointer
300 int8 check=0; // Checksum is calculated between '$' and '*'
301  
302 delay(SEND_DELAY);
303 putc('$');
304 delay(SEND_DELAY);
1703 kakl 305 sprintf(output,"M%s \0",VER);
1597 kakl 306 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1703 kakl 307 sprintf(output,"%Lu \0", seq);
1597 kakl 308 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1703 kakl 309 sprintf(output,"%Ld \0", ta);
1597 kakl 310 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1703 kakl 311 sprintf(output,"%Ld \0", to1);
1597 kakl 312 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1703 kakl 313 sprintf(output,"%Ld \0", to2);
1597 kakl 314 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1705 kakl 315 sprintf(output,"%Ld \0",tTouch);
1597 kakl 316 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1703 kakl 317 sprintf(output,"%u \0", heat);
1597 kakl 318 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1703 kakl 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);
1597 kakl 322 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j++]); }
323 delay(SEND_DELAY);
324 }
1703 kakl 325  
1597 kakl 326 //---WDT
327 restart_wdt();
328 }
329 }
330  
331  
1705 kakl 332 #include "dbloader.c" // Space reservation for the BootLoader