Rev Author Line No. Line
1274 kakl 1 /************ SMB driver ************/
2  
3 #define SA 0x00 // Slave Address (0 for single slave / 0x5A<<1 default)
4 #define RAM_Access 0x00 // RAM access command
5 #define RAM_Tobj1 0x07 // To1 address in the RAM
6 #define RAM_Tamb 0x06 // Ta address in the RAM
7  
8 //*High and Low level of clock
9 #define HIGHLEV 40 // max. 50us
10 #define LOWLEV 100 // max. 30ms
11 #define TBUF 20
12  
13 //SMBus control signals
14 #define SCL PIN_B0
15 #define SDA PIN_B1
16  
17 #define mSDA_HIGH() output_float(SDA); // SDA float
18 #define mSDA_LOW() output_low(SDA); // SDA low
19 #define mSCL_HIGH() output_float(SCL); //output_high(SCL); // SCL high
20 #define mSCL_LOW() output_low(SCL); // SCL low
21  
22 #define ACK 0
23 #define NACK 1
24  
25 //**********************************************************************************************
26 // START CONDITION ON SMBus
27 //**********************************************************************************************
28 //Name: START_bit
29 //Function: Generate START condition on SMBus
30 //Parameters: No
31 //Return: No
32 //Comments: Refer to "System Managment BUS(SMBus) specification Version 2.0"
33 // or AN"SMBus communication with MLX90614" on the website www.melexis.com
34 //**********************************************************************************************
35 void SMB_START_bit(void)
36 {
37 disable_interrupts(GLOBAL);
38 mSDA_HIGH(); // Set SDA line
39 delay_us( TBUF ); // Wait a few microseconds
40 mSCL_HIGH(); // Set SCL line
41 delay_us( TBUF ); // Generate bus free time between Stop
42 // and Start condition (Tbuf=4.7us min)
43 mSDA_LOW(); // Clear SDA line
44 delay_us( TBUF ); // Hold time after (Repeated) Start
45 // Condition. After this period, the first clock is generated.
46 //(Thd:sta=4.0us min)
47 mSCL_LOW(); // Clear SCL line
48 enable_interrupts(GLOBAL);
49 delay_us( TBUF ); // Wait a few microseconds
50 }
51 //*********************************************************************************************
52 // STOP CONDITION ON SMBus
53 //*********************************************************************************************
54 //Name: STOPbit
55 //Function: Generate STOP condition on SMBus
56 //Parameters: No
57 //Return: No
58 //Comments: Refer to "System Managment BUS(SMBus) specification Version 2.0"
59 // or AN"SMBus communication with MLX90614" on the website www.melexis.com
60 //*********************************************************************************************
61 void SMB_STOP_bit(void)
62 {
63 disable_interrupts(GLOBAL);
64 mSDA_HIGH();
65 mSCL_LOW(); // Clear SCL line
66 delay_us( TBUF ); // Wait a few microseconds
67 mSDA_LOW(); // Clear SDA line
68 delay_us( TBUF ); // Wait a few microseconds
69 mSCL_HIGH(); // Set SCL line
70 delay_us( TBUF ); // Stop condition setup time(Tsu:sto=4.0us min)
71 mSDA_HIGH(); // Set SDA line
72 enable_interrupts(GLOBAL);
73 }
74  
75  
76 void SMB_send_bit(unsigned char bit_out)
77 {
78 disable_interrupts(GLOBAL);
79 if(bit_out==0) {mSDA_LOW();}
80 else {mSDA_HIGH();}
81 delay_us(3);
82 mSCL_HIGH(); // Set SCL line
83 delay_us( HIGHLEV ); // High Level of Clock Pulse
84 mSCL_LOW(); // Clear SCL line
85 delay_us( LOWLEV ); // Low Level of Clock Pulse
86 // mSDA_HIGH(); // Master release SDA line ,
87 enable_interrupts(GLOBAL);
88 return;
89 }
90  
91 unsigned char SMB_Receive_bit(void)
92 {
93 unsigned char Ack_bit;
94  
95 disable_interrupts(GLOBAL);
96 mSDA_HIGH(); //_SDA_IO=1; // SDA-input
97 mSCL_HIGH(); // Set SCL line
98 delay_us( HIGHLEV ); // High Level of Clock Pulse
99 if(input(SDA)) Ack_bit=1; // \ Read acknowledgment bit, save it in Ack_bit
100 else Ack_bit=0; // /
101 mSCL_LOW(); // Clear SCL line
102 delay_us( LOWLEV ); // Low Level of Clock Pulse
103 enable_interrupts(GLOBAL);
104  
105 return Ack_bit;
106 }
107  
108  
109 //*********************************************************************************************
110 // TRANSMIT DATA ON SMBus
111 //*********************************************************************************************
112 //Name: TX_byte
113 //Function: Send a byte on SMBus
114 //Parameters: TX_buffer ( the byte which will be send on the SMBus )
115 //Return: Ack_bit ( acknowledgment bit )
116 //Comments: Sends MSbit first
117 //*********************************************************************************************
118 unsigned char SMB_TX_byte(unsigned char Tx_buffer)
119 {
120 unsigned char Bit_counter;
121 unsigned char Ack_bit;
122 unsigned char bit_out;
123  
124 for(Bit_counter=8; Bit_counter; Bit_counter--)
125 {
126 if(Tx_buffer&0x80) bit_out=1; // If the current bit of Tx_buffer is 1 set bit_out
127 else bit_out=0; // else clear bit_out
128  
129 SMB_send_bit(bit_out); // Send the current bit on SDA
130 Tx_buffer<<=1; // Get next bit for checking
131 }
132  
133 Ack_bit=SMB_Receive_bit(); // Get acknowledgment bit
134  
135 return Ack_bit;
136 }// End of TX_bite()
137  
138 //*********************************************************************************************
139 // RECEIVE DATA ON SMBus
140 //*********************************************************************************************
141 //Name: RX_byte
142 //Function: Receive a byte on SMBus
143 //Parameters: ack_nack (ackowlegment bit)
144 //Return: RX_buffer(Received byte)
145 //Comments: MSbit is received first
146 //*********************************************************************************************
147 unsigned char SMB_RX_byte(unsigned char ack_nack)
148 {
149 unsigned char RX_buffer;
150 unsigned char Bit_Counter;
151  
152 for(Bit_Counter=8; Bit_Counter; Bit_Counter--)
153 {
154 if(SMB_Receive_bit()) // Get a bit from the SDA line
155 {
156 RX_buffer <<= 1; // If the bit is HIGH save 1 in RX_buffer
157 RX_buffer |=0b00000001;
158 }
159 else
160 {
161 RX_buffer <<= 1; // If the bit is LOW save 0 in RX_buffer
162 RX_buffer &=0b11111110;
163 }
164 }
165  
166 SMB_send_bit(ack_nack); // Sends acknowledgment bit
167  
168 return RX_buffer;
169 }
170  
171  
172 unsigned char PEC_calculation(unsigned char pec[]) // CRC calculation
173 {
174 unsigned char crc[6];
175 unsigned char BitPosition=47;
176 unsigned char shift;
177 unsigned char i;
178 unsigned char j;
179 unsigned char temp;
180  
181 do
182 {
183 crc[5]=0; /* Load CRC value 0x000000000107 */
184 crc[4]=0;
185 crc[3]=0;
186 crc[2]=0;
187 crc[1]=0x01;
188 crc[0]=0x07;
189 BitPosition=47; /* Set maximum bit position at 47 */
190 shift=0;
191  
192 //Find first 1 in the transmited message
193 i=5; /* Set highest index */
194 j=0;
195 while((pec[i]&(0x80>>j))==0 && i>0)
196 {
197 BitPosition--;
198 if(j<7)
199 {
200 j++;
201 }
202 else
203 {
204 j=0x00;
205 i--;
206 }
207 }/*End of while */
208  
209 shift=BitPosition-8; /*Get shift value for crc value*/
210  
211  
212 //Shift crc value
213 while(shift)
214 {
215 for(i=5; i<0xFF; i--)
216 {
217 if((crc[i-1]&0x80) && (i>0))
218 {
219 temp=1;
220 }
221 else
222 {
223 temp=0;
224 }
225 crc[i]<<=1;
226 crc[i]+=temp;
227 }/*End of for*/
228 shift--;
229 }/*End of while*/
230  
231 //Exclusive OR between pec and crc
232 for(i=0; i<=5; i++)
233 {
234 pec[i] ^=crc[i];
235 }/*End of for*/
236 } while(BitPosition>8);/*End of do-while*/
237  
238 return pec[0];
239 }/*End of PEC_calculation*/
240  
241 int16 ReadTemp(int8 addr, int8 select) // Read sensor RAM
242 {
243 unsigned char arr[6]; // Buffer for the sent bytes
244 int8 crc; // Readed CRC
245 int16 temp; // Readed temperature
246  
247 addr<<=1;
248  
249 SMB_STOP_bit(); //If slave send NACK stop comunication
250 SMB_START_bit(); //Start condition
251 SMB_TX_byte(addr);
252 SMB_TX_byte(RAM_Access|select);
253 SMB_START_bit(); //Repeated Start condition
254 SMB_TX_byte(addr);
255 arr[2]=SMB_RX_byte(ACK); //Read low data,master must send ACK
256 arr[1]=SMB_RX_byte(ACK); //Read high data,master must send ACK
257 temp=MAKE16(arr[1],arr[2]);
258 crc=SMB_RX_byte(NACK); //Read PEC byte, master must send NACK
259 SMB_STOP_bit(); //Stop condition
260  
261 arr[5]=addr;
262 arr[4]=RAM_Access|select;
263 arr[3]=addr;
264 arr[0]=0;
265 if (crc != PEC_calculation(arr)) temp=0; // Calculate and check CRC
266  
267 return temp;
268 }
269  
270 void main()
271 {
272 unsigned int16 temp, tempa;
273 signed int16 ta, to;
274  
275 setup_adc_ports(NO_ANALOGS);
276 setup_adc(ADC_OFF);
277 setup_psp(PSP_DISABLED);
278 setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
279 setup_timer_1(T1_DISABLED);
280 setup_timer_2(T2_DISABLED,0,1);
281  
282 output_low(KLAKSON); // Ticho
283 output_high(LED); // Blik
284 delay_ms(50);
285 output_low(LED);
286 printf("\n\r\n\rVER: %s\n\r\n\r", VER); // Vypis verzi
287  
288 enable_interrupts(INT_RDA);
289 enable_interrupts(GLOBAL);
290  
291 flag=false;
292  
293 while (true)
294 {
295 float ta1, ta2, to1, to2;
296 int16 s1, s2, s3, s4, s5, s6;
297 int8 c;
298 int8 tlacitko;
299  
300 if (flag)
301 {
302 flag=false;
303  
304 output_high(KLAKSON);
305 delay_ms(400);
306 output_low(KLAKSON);
307 delay_ms(100);
308 output_high(KLAKSON);
309 delay_ms(700);
310 output_low(KLAKSON);
311 }
312  
313 tlacitko=0;
314  
315 tempa=ReadTemp(1, RAM_Tamb); // Read temperatures from sensor
316 temp=ReadTemp(1, RAM_Tobj1);
317 to=(signed int16)(temp*2-27315);
318 ta=(signed int16)(tempa*2-27315);
319 ta1=(float)ta/100;
320 to1=(float)to/100;
321  
322 if(!input(TL)) tlacitko=1;
323  
324 tempa=ReadTemp(2, RAM_Tamb); // Read temperatures from sensor
325 temp=ReadTemp(2, RAM_Tobj1);
326 to=(signed int16)(temp*2-27315);
327 ta=(signed int16)(tempa*2-27315);
328 ta2=(float)ta/100;
329 to2=(float)to/100;
330 // printf("T2 %.1g %.1g ",(float)ta/100,(float)to/100);
331  
332 // printf("S1 %Lu ", sonar_ping(SONAR1));
333 if(!input(TL)) tlacitko=1;
334 output_high(LED);
335 s1=sonar_ping(SONAR1);
336 output_low(LED);
337 if(!input(TL)) tlacitko=1;
338 s2=sonar_ping(SONAR2);
339 if(!input(TL)) tlacitko=1;
340 s3=sonar_ping(SONAR3);
341 if(!input(TL)) tlacitko=1;
342 s4=sonar_ping(SONAR4);
343 if(!input(TL)) tlacitko=1;
344 s5=sonar_ping(SONAR5);
345 if(!input(TL)) tlacitko=1;
346 s6=sonar_ping(SONAR6);
347 if(!input(TL)) tlacitko=1;
348 c=cmps_azimuth();
349 if(!input(TL)) tlacitko=1;
350  
351 printf("#T1 %.1g %.1g T2 %.1g %.1g ",ta1,to1,ta2,to2);
352 printf("S1 %Lu S2 %Lu S3 %Lu S4 %Lu S5 %Lu S6 %Lu C %u TL %u\n\r",s1,s2,s3,s4,s5,s6,c,tlacitko);
353 }
354  
355 }