Rev Author Line No. Line
1597 kakl 1 /**** IR Mrakomer 4 ****/
2 #define VERSION "4.1"
3 #define ID "$Id: irmrak4.c 1706 2010-12-05 19:36:36Z 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]);
1706 kakl 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 sequence inside[1/100 C] sky[1/100 C] sky[1/100 C] ");
60 printf("ambient[1/100 C] heating[s] dome[s] check\r\n\r\n");
1705 kakl 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 CREN=0; CREN=1; // Reinitialise USART
249  
250 seq++; // Increment the number of measurement
251  
252 tempa=ReadTemp(SA, RAM_Tamb); // Read temperatures from sensor
253 ta=tempa*2-27315; // °K -> °C
254  
255 temp=ReadTemp(SA, RAM_Tobj1);
256 to1=temp*2-27315;
257 temp=ReadTemp(SA, RAM_Tobj2);
258 to2=temp*2-27315;
259  
1703 kakl 260 touch_present(); //Issues a reset of Touch Memory device
261 touch_write_byte(0xCC);
262 touch_write_byte(0x44);
263  
264 //---WDT
265 restart_wdt();
266 delay(MEASURE_DELAY); // Delay to a next measurement
267  
268 {
269 int8 SN[10];
270 int8 n;
271  
272 touch_present(); //Issues a reset and returns true if the touch device is there.
273 touch_write_byte(0xCC);
274 touch_write_byte(0xBE);
275 for(n=0;n<9;n++) SN[n]=touch_read_byte();
276 tLSB=SN[0];
277 tMSB=SN[1];
278 if ((SN[8]==TM_check_CRC(SN,8))&&(SN[7]==0x10)) // Check CRC and family code to prevent O's error
279 {
280 tTouch=make16(tMSB,tLSB);
1705 kakl 281 tTouch=tTouch*6+tTouch/4; // 1bit = 0,0625gradC recalculate to 1/100gradC
1703 kakl 282 }
283 else
284 {
1705 kakl 285 tTouch=-27315;
1703 kakl 286 }
287 }
288  
1705 kakl 289 if(automatic) // Solve automatic mode
290 {
291 if(ta<1800) heat=MAXHEAT; // Need heating
292 if((abs(to1-to2)<200)&&(tTouch>to1)&&(abs(tTouch/4-to1)>500))
293 open=MAXOPEN; // Open the dome
294 }
295  
1597 kakl 296 { // printf
297 char output[8]; // Output buffer
298 int8 j; // String pointer
299 int8 check=0; // Checksum is calculated between '$' and '*'
300  
301 delay(SEND_DELAY);
302 putc('$');
303 delay(SEND_DELAY);
1703 kakl 304 sprintf(output,"M%s \0",VER);
1597 kakl 305 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1703 kakl 306 sprintf(output,"%Lu \0", seq);
1597 kakl 307 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1703 kakl 308 sprintf(output,"%Ld \0", ta);
1597 kakl 309 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1703 kakl 310 sprintf(output,"%Ld \0", to1);
1597 kakl 311 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1703 kakl 312 sprintf(output,"%Ld \0", to2);
1597 kakl 313 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1705 kakl 314 sprintf(output,"%Ld \0",tTouch);
1597 kakl 315 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1703 kakl 316 sprintf(output,"%u \0", heat);
1597 kakl 317 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1703 kakl 318 sprintf(output,"%u \0", open);
319 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
320 sprintf(output,"*%X\r\n\0", check);
1597 kakl 321 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j++]); }
322 delay(SEND_DELAY);
323 }
1703 kakl 324  
1597 kakl 325 //---WDT
326 restart_wdt();
327 }
328 }
329  
330  
1705 kakl 331 #include "dbloader.c" // Space reservation for the BootLoader