Rev 1274 Rev 1275
1 /************ SMB driver ************/ 1 /************ SMB driver ************/
2   2  
3 #define SA 0x00 // Slave Address (0 for single slave / 0x5A<<1 default) 3 #define SA 0x00 // Slave Address (0 for single slave / 0x5A<<1 default)
4 #define RAM_Access 0x00 // RAM access command 4 #define RAM_Access 0x00 // RAM access command
5 #define RAM_Tobj1 0x07 // To1 address in the RAM 5 #define RAM_Tobj1 0x07 // To1 address in the RAM
6 #define RAM_Tamb 0x06 // Ta address in the RAM 6 #define RAM_Tamb 0x06 // Ta address in the RAM
7   7  
-   8  
8 //*High and Low level of clock 9 //*High and Low level of clock
9 #define HIGHLEV 40 // max. 50us 10 #define HIGHLEV 40 // max. 50us
10 #define LOWLEV 100 // max. 30ms 11 #define LOWLEV 100 // max. 30ms
11 #define TBUF 20 12 #define TBUF 20
12   13  
13 //SMBus control signals 14 //SMBus control signals
14 #define SCL PIN_B0 15 #define SCL PIN_B0
15 #define SDA PIN_B1 16 #define SDA PIN_B1
16   17  
17 #define mSDA_HIGH() output_float(SDA); // SDA float 18 #define mSDA_HIGH() output_float(SDA); // SDA float
18 #define mSDA_LOW() output_low(SDA); // SDA low 19 #define mSDA_LOW() output_low(SDA); // SDA low
19 #define mSCL_HIGH() output_float(SCL); //output_high(SCL); // SCL high 20 #define mSCL_HIGH() output_float(SCL); //output_high(SCL); // SCL high
20 #define mSCL_LOW() output_low(SCL); // SCL low 21 #define mSCL_LOW() output_low(SCL); // SCL low
21   22  
22 #define ACK 0 23 #define ACK 0
23 #define NACK 1 24 #define NACK 1
24   25  
25 //********************************************************************************************** 26 //**********************************************************************************************
26 // START CONDITION ON SMBus 27 // START CONDITION ON SMBus
27 //********************************************************************************************** 28 //**********************************************************************************************
28 //Name: START_bit 29 //Name: START_bit
29 //Function: Generate START condition on SMBus 30 //Function: Generate START condition on SMBus
30 //Parameters: No 31 //Parameters: No
31 //Return: No 32 //Return: No
32 //Comments: Refer to "System Managment BUS(SMBus) specification Version 2.0" 33 //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 // or AN"SMBus communication with MLX90614" on the website www.melexis.com
34 //********************************************************************************************** 35 //**********************************************************************************************
35 void SMB_START_bit(void) 36 void SMB_START_bit(void)
36 { 37 {
37 disable_interrupts(GLOBAL); 38 // disable_interrupts(GLOBAL);
38 mSDA_HIGH(); // Set SDA line 39 mSDA_HIGH(); // Set SDA line
39 delay_us( TBUF ); // Wait a few microseconds 40 delay_us( TBUF ); // Wait a few microseconds
40 mSCL_HIGH(); // Set SCL line 41 mSCL_HIGH(); // Set SCL line
41 delay_us( TBUF ); // Generate bus free time between Stop 42 delay_us( TBUF ); // Generate bus free time between Stop
42 // and Start condition (Tbuf=4.7us min) 43 // and Start condition (Tbuf=4.7us min)
43 mSDA_LOW(); // Clear SDA line 44 mSDA_LOW(); // Clear SDA line
44 delay_us( TBUF ); // Hold time after (Repeated) Start 45 delay_us( TBUF ); // Hold time after (Repeated) Start
45 // Condition. After this period, the first clock is generated. 46 // Condition. After this period, the first clock is generated.
46 //(Thd:sta=4.0us min) 47 //(Thd:sta=4.0us min)
47 mSCL_LOW(); // Clear SCL line 48 mSCL_LOW(); // Clear SCL line
48 enable_interrupts(GLOBAL); 49 // enable_interrupts(GLOBAL);
49 delay_us( TBUF ); // Wait a few microseconds 50 delay_us( TBUF ); // Wait a few microseconds
-   51
-   52 toggle_dome();
50 } 53 }
51 //********************************************************************************************* 54 //*********************************************************************************************
52 // STOP CONDITION ON SMBus 55 // STOP CONDITION ON SMBus
53 //********************************************************************************************* 56 //*********************************************************************************************
54 //Name: STOPbit 57 //Name: STOPbit
55 //Function: Generate STOP condition on SMBus 58 //Function: Generate STOP condition on SMBus
56 //Parameters: No 59 //Parameters: No
57 //Return: No 60 //Return: No
58 //Comments: Refer to "System Managment BUS(SMBus) specification Version 2.0" 61 //Comments: Refer to "System Managment BUS(SMBus) specification Version 2.0"
59 // or AN"SMBus communication with MLX90614" on the website www.melexis.com 62 // or AN"SMBus communication with MLX90614" on the website www.melexis.com
60 //********************************************************************************************* 63 //*********************************************************************************************
61 void SMB_STOP_bit(void) 64 void SMB_STOP_bit(void)
62 { 65 {
63 disable_interrupts(GLOBAL); 66 // disable_interrupts(GLOBAL);
64 mSDA_HIGH(); 67 mSDA_HIGH();
65 mSCL_LOW(); // Clear SCL line 68 mSCL_LOW(); // Clear SCL line
66 delay_us( TBUF ); // Wait a few microseconds 69 delay_us( TBUF ); // Wait a few microseconds
67 mSDA_LOW(); // Clear SDA line 70 mSDA_LOW(); // Clear SDA line
68 delay_us( TBUF ); // Wait a few microseconds 71 delay_us( TBUF ); // Wait a few microseconds
69 mSCL_HIGH(); // Set SCL line 72 mSCL_HIGH(); // Set SCL line
70 delay_us( TBUF ); // Stop condition setup time(Tsu:sto=4.0us min) 73 delay_us( TBUF ); // Stop condition setup time(Tsu:sto=4.0us min)
71 mSDA_HIGH(); // Set SDA line 74 mSDA_HIGH(); // Set SDA line
72 enable_interrupts(GLOBAL); 75 // enable_interrupts(GLOBAL);
-   76  
-   77 toggle_dome();
73 } 78 }
74   79  
75   80  
76 void SMB_send_bit(unsigned char bit_out) 81 void SMB_send_bit(unsigned char bit_out)
77 { 82 {
78 disable_interrupts(GLOBAL); 83 // disable_interrupts(GLOBAL);
79 if(bit_out==0) {mSDA_LOW();} 84 if(bit_out==0) {mSDA_LOW();}
80 else {mSDA_HIGH();} 85 else {mSDA_HIGH();}
81 delay_us(3); 86 delay_us(3);
82 mSCL_HIGH(); // Set SCL line 87 mSCL_HIGH(); // Set SCL line
83 delay_us( HIGHLEV ); // High Level of Clock Pulse 88 delay_us( HIGHLEV ); // High Level of Clock Pulse
84 mSCL_LOW(); // Clear SCL line 89 mSCL_LOW(); // Clear SCL line
85 delay_us( LOWLEV ); // Low Level of Clock Pulse 90 delay_us( LOWLEV ); // Low Level of Clock Pulse
86 // mSDA_HIGH(); // Master release SDA line , 91 // mSDA_HIGH(); // Master release SDA line ,
87 enable_interrupts(GLOBAL); 92 // enable_interrupts(GLOBAL);
-   93  
-   94 toggle_dome();
88 return; 95 return;
89 } 96 }
90   97  
91 unsigned char SMB_Receive_bit(void) 98 unsigned char SMB_Receive_bit(void)
92 { 99 {
93 unsigned char Ack_bit; 100 unsigned char Ack_bit;
94   101  
95 disable_interrupts(GLOBAL); 102 // disable_interrupts(GLOBAL);
96 mSDA_HIGH(); //_SDA_IO=1; // SDA-input 103 mSDA_HIGH(); //_SDA_IO=1; // SDA-input
97 mSCL_HIGH(); // Set SCL line 104 mSCL_HIGH(); // Set SCL line
98 delay_us( HIGHLEV ); // High Level of Clock Pulse 105 delay_us( HIGHLEV ); // High Level of Clock Pulse
99 if(input(SDA)) Ack_bit=1; // \ Read acknowledgment bit, save it in Ack_bit 106 if(input(SDA)) Ack_bit=1; // \ Read acknowledgment bit, save it in Ack_bit
100 else Ack_bit=0; // / 107 else Ack_bit=0; // /
101 mSCL_LOW(); // Clear SCL line 108 mSCL_LOW(); // Clear SCL line
102 delay_us( LOWLEV ); // Low Level of Clock Pulse 109 delay_us( LOWLEV ); // Low Level of Clock Pulse
103 enable_interrupts(GLOBAL); 110 // enable_interrupts(GLOBAL);
104   111  
-   112 toggle_dome();
105 return Ack_bit; 113 return Ack_bit;
106 } 114 }
107   115  
108   116  
109 //********************************************************************************************* 117 //*********************************************************************************************
110 // TRANSMIT DATA ON SMBus 118 // TRANSMIT DATA ON SMBus
111 //********************************************************************************************* 119 //*********************************************************************************************
112 //Name: TX_byte 120 //Name: TX_byte
113 //Function: Send a byte on SMBus 121 //Function: Send a byte on SMBus
114 //Parameters: TX_buffer ( the byte which will be send on the SMBus ) 122 //Parameters: TX_buffer ( the byte which will be send on the SMBus )
115 //Return: Ack_bit ( acknowledgment bit ) 123 //Return: Ack_bit ( acknowledgment bit )
116 //Comments: Sends MSbit first 124 //Comments: Sends MSbit first
117 //********************************************************************************************* 125 //*********************************************************************************************
118 unsigned char SMB_TX_byte(unsigned char Tx_buffer) 126 unsigned char SMB_TX_byte(unsigned char Tx_buffer)
119 { 127 {
120 unsigned char Bit_counter; 128 unsigned char Bit_counter;
121 unsigned char Ack_bit; 129 unsigned char Ack_bit;
122 unsigned char bit_out; 130 unsigned char bit_out;
123   131  
124 for(Bit_counter=8; Bit_counter; Bit_counter--) 132 for(Bit_counter=8; Bit_counter; Bit_counter--)
125 { 133 {
126 if(Tx_buffer&0x80) bit_out=1; // If the current bit of Tx_buffer is 1 set bit_out 134 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 135 else bit_out=0; // else clear bit_out
128   136  
129 SMB_send_bit(bit_out); // Send the current bit on SDA 137 SMB_send_bit(bit_out); // Send the current bit on SDA
130 Tx_buffer<<=1; // Get next bit for checking 138 Tx_buffer<<=1; // Get next bit for checking
131 } 139 }
132   140  
133 Ack_bit=SMB_Receive_bit(); // Get acknowledgment bit 141 Ack_bit=SMB_Receive_bit(); // Get acknowledgment bit
134   142  
135 return Ack_bit; 143 return Ack_bit;
136 }// End of TX_bite() 144 }
137   145  
138 //********************************************************************************************* 146 //*********************************************************************************************
139 // RECEIVE DATA ON SMBus 147 // RECEIVE DATA ON SMBus
140 //********************************************************************************************* 148 //*********************************************************************************************
141 //Name: RX_byte 149 //Name: RX_byte
142 //Function: Receive a byte on SMBus 150 //Function: Receive a byte on SMBus
143 //Parameters: ack_nack (ackowlegment bit) 151 //Parameters: ack_nack (ackowlegment bit)
144 //Return: RX_buffer(Received byte) 152 //Return: RX_buffer(Received byte)
145 //Comments: MSbit is received first 153 //Comments: MSbit is received first
146 //********************************************************************************************* 154 //*********************************************************************************************
147 unsigned char SMB_RX_byte(unsigned char ack_nack) 155 unsigned char SMB_RX_byte(unsigned char ack_nack)
148 { 156 {
149 unsigned char RX_buffer; 157 unsigned char RX_buffer;
150 unsigned char Bit_Counter; 158 unsigned char Bit_Counter;
151   159  
152 for(Bit_Counter=8; Bit_Counter; Bit_Counter--) 160 for(Bit_Counter=8; Bit_Counter; Bit_Counter--)
153 { 161 {
154 if(SMB_Receive_bit()) // Get a bit from the SDA line 162 if(SMB_Receive_bit()) // Get a bit from the SDA line
155 { 163 {
156 RX_buffer <<= 1; // If the bit is HIGH save 1 in RX_buffer 164 RX_buffer <<= 1; // If the bit is HIGH save 1 in RX_buffer
157 RX_buffer |=0b00000001; 165 RX_buffer |=0b00000001;
158 } 166 }
159 else 167 else
160 { 168 {
161 RX_buffer <<= 1; // If the bit is LOW save 0 in RX_buffer 169 RX_buffer <<= 1; // If the bit is LOW save 0 in RX_buffer
162 RX_buffer &=0b11111110; 170 RX_buffer &=0b11111110;
163 } 171 }
164 } 172 }
165   173  
166 SMB_send_bit(ack_nack); // Sends acknowledgment bit 174 SMB_send_bit(ack_nack); // Sends acknowledgment bit
167   175  
168 return RX_buffer; 176 return RX_buffer;
169 } 177 }
170   178  
171   179  
172 unsigned char PEC_calculation(unsigned char pec[]) // CRC calculation 180 unsigned char PEC_calculation(unsigned char pec[]) // CRC calculation
173 { 181 {
174 unsigned char crc[6]; 182 unsigned char crc[6];
175 unsigned char BitPosition=47; 183 unsigned char BitPosition=47;
176 unsigned char shift; 184 unsigned char shift;
177 unsigned char i; 185 unsigned char i;
178 unsigned char j; 186 unsigned char j;
179 unsigned char temp; 187 unsigned char temp;
180   188  
181 do 189 do
182 { 190 {
183 crc[5]=0; /* Load CRC value 0x000000000107 */ 191 crc[5]=0; /* Load CRC value 0x000000000107 */
184 crc[4]=0; 192 crc[4]=0;
185 crc[3]=0; 193 crc[3]=0;
186 crc[2]=0; 194 crc[2]=0;
187 crc[1]=0x01; 195 crc[1]=0x01;
188 crc[0]=0x07; 196 crc[0]=0x07;
189 BitPosition=47; /* Set maximum bit position at 47 */ 197 BitPosition=47; /* Set maximum bit position at 47 */
190 shift=0; 198 shift=0;
191   199  
192 //Find first 1 in the transmited message 200 //Find first 1 in the transmited message
193 i=5; /* Set highest index */ 201 i=5; /* Set highest index */
194 j=0; 202 j=0;
195 while((pec[i]&(0x80>>j))==0 && i>0) 203 while((pec[i]&(0x80>>j))==0 && i>0)
196 { 204 {
197 BitPosition--; 205 BitPosition--;
198 if(j<7) 206 if(j<7)
199 { 207 {
200 j++; 208 j++;
201 } 209 }
202 else 210 else
203 { 211 {
204 j=0x00; 212 j=0x00;
205 i--; 213 i--;
206 } 214 }
207 }/*End of while */ 215 }
208   216  
209 shift=BitPosition-8; /*Get shift value for crc value*/ 217 shift=BitPosition-8; /*Get shift value for crc value*/
210   218  
211   219  
212 //Shift crc value 220 //Shift crc value
213 while(shift) 221 while(shift)
214 { 222 {
215 for(i=5; i<0xFF; i--) 223 for(i=5; i<0xFF; i--)
216 { 224 {
217 if((crc[i-1]&0x80) && (i>0)) 225 if((crc[i-1]&0x80) && (i>0))
218 { 226 {
219 temp=1; 227 temp=1;
220 } 228 }
221 else 229 else
222 { 230 {
223 temp=0; 231 temp=0;
224 } 232 }
225 crc[i]<<=1; 233 crc[i]<<=1;
226 crc[i]+=temp; 234 crc[i]+=temp;
227 }/*End of for*/ 235 }
228 shift--; 236 shift--;
229 }/*End of while*/ 237 }
230   238  
231 //Exclusive OR between pec and crc 239 //Exclusive OR between pec and crc
232 for(i=0; i<=5; i++) 240 for(i=0; i<=5; i++)
233 { 241 {
234 pec[i] ^=crc[i]; 242 pec[i] ^=crc[i];
235 }/*End of for*/ 243 }
236 } while(BitPosition>8);/*End of do-while*/ 244 } while(BitPosition>8);/*End of do-while*/
237   245  
238 return pec[0]; 246 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 } 247 }