?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{BLAME START}

library

?curdirlinks? -

Blame information for rev 6

Line No. Rev Author Line
1 6 kaklik //*****************************************************************************
2 // File Name : ds2450.c
3 // Title : Dallas 1-Wire DS2450 A2D Sensor Library
4 // Revision : 5
5 // Notes :
6 // Target MCU : Atmel AVR series
7 // Editor Tabs : 4
8 //
9 //*****************************************************************************
10  
11 //----- Include Files ---------------------------------------------------------
12 #include <string.h> // include string support
13 #include "timer128.h"
14 #include "dallas.h" // include dallas support
15 #include "ds2450.h" // include ds2450 support
16 #include "rprintf.h"
17  
18 //----- Functions ---------------------------------------------------------------
19  
20 /*--------------------------------------------------------------------------
21 * ds2450Chan2Addr: converts the channel to the address in RAM
22 * input........... channel - the channel to get the address for [A-D]
23 * page - the page in RAM that we are dealing with
24 * address - where the address is stored
25 * returns......... the corresponding error or DALLAS_NO_ERROR
26 *-------------------------------------------------------------------------*/
27 static u08 ds2450Chan2Addr(u08 channel, u08 page, u16 *address);
28  
29 void ds2450Init(void)
30 {
31 // initialize the dallas 1-wire
32 dallasInit();
33 }
34  
35 u08 ds2450Setup(dallas_rom_id_T* rom_id, u08 channel, u08 resolution, u08 range)
36 {
37 u08 error;
38 u08 data[2];
39 u16 address;
40  
41 // check resolution
42 if (resolution > DS2450_RES_MAX)
43 return DALLAS_RESOLUTION_ERROR;
44  
45 // check address
46 error = dallasAddressCheck(rom_id, DS2450_FAMILY);
47 if (error != DALLAS_NO_ERROR)
48 return error;
49  
50 // get address
51 strupr(&channel);
52 error = ds2450Chan2Addr(channel, DS2450_SETUP_PAGE, &address); //find starting address
53 if (error != DALLAS_NO_ERROR)
54 return error;
55  
56 // convert to valid resolution - 16 bits = 0x00
57 if (resolution == 16)
58 resolution = 0x00;
59  
60 // read in current digital output settings
61 error = dallasReadRAM(rom_id, address, 1, data);
62 if (error != DALLAS_NO_ERROR)
63 return error;
64  
65 // maintain digital output portion and add new resolution
66 data[0] = (data[0] & 0xF0) | resolution;
67  
68 // maintain alarm states and add new range
69 data[1] = (data[1] & 0xFE) | range;
70  
71 // actually write config, handles CRC too
72 error = dallasWriteRAM(rom_id, address, 2, data);
73 if (error != DALLAS_NO_ERROR)
74 return error;
75  
76 // Normally, the DS2450 is designed to run off of parasite power from the data line
77 // Typically the master (us) strongly pulls high long enough to power the conversion, so
78 // there is inherintly a long () delay introduced. Since the A2D code is designed to
79 // work for devices that use external power, we can elliminate this delay by writting
80 // the following byte per the DS2450 datasheet.
81 data[0] = DS2450_VCC_FLAG;
82 error = dallasWriteRAM(rom_id, DS2450_VCC_ADDR, 1, &data[0]);
83 if (error != DALLAS_NO_ERROR)
84 return error;
85  
86 // verify the data
87 error = dallasReadRAM(rom_id, address, 2, data);
88 if (error != DALLAS_NO_ERROR)
89 return error;
90  
91 if ((data[0] & 0x0F) != resolution)
92 return DALLAS_VERIFY_ERROR;
93 if ((data[1] & 0x01) != range)
94 return DALLAS_VERIFY_ERROR;
95  
96 return DALLAS_NO_ERROR;
97 }
98  
99 u08 ds2450Start(dallas_rom_id_T* rom_id, u08 channel)
100 {
101 u08 mask;
102 u08 error;
103 u08 crc[2];
104  
105 // check address
106 error = dallasAddressCheck(rom_id, DS2450_FAMILY);
107 if (error != DALLAS_NO_ERROR)
108 return error;
109  
110 // make sure the channel is a capital letter
111 strupr(&channel);
112 // convert to integer 0 to 3
113 channel -= 'A';
114  
115 // make sure channel is a valid value
116 if (channel > 3)
117 return DALLAS_INVALID_CHANNEL;
118  
119 // shift over to construct input select mask
120 mask = 0x01 << channel;
121  
122 // reset and select node
123 error = dallasMatchROM(rom_id);
124 if (error != DALLAS_NO_ERROR)
125 return error;
126  
127 // send convert command
128 dallasWriteByte(DS2450_CONVERT);
129 // input select mask
130 dallasWriteByte(mask);
131 // shift over some more for "read-out" control
132 mask = mask << channel;
133  
134 // set coresponding output buffer to zero
135 dallasWriteByte(mask);
136  
137 // we must read 2byte CRC16 to start the conversion:
138 crc[0] = dallasReadByte();
139 crc[1] = dallasReadByte();
140  
141 //replace with explicit CRC posibilities lookup table
142 // if (crc[0] == 0xFF && crc[1] == 0xFF)
143 // return DALLAS_DEVICE_ERROR; //if CRC = all one's, no one is paying attention
144  
145 return DALLAS_NO_ERROR;
146 }
147  
148 u08 ds2450Result(dallas_rom_id_T* rom_id, u08 channel, u16* result)
149 {
150 u08 data[2];
151 u08 error;
152 u16 address;
153 u08 resolution;
154  
155 // check address
156 error = dallasAddressCheck(rom_id, DS2450_FAMILY);
157 if( error != DALLAS_NO_ERROR)
158 return error;
159  
160 // get the RAM address for the data for the channel
161 strupr(&channel);
162 error = ds2450Chan2Addr(channel, DS2450_DATA_PAGE, &address);
163 if (error != DALLAS_NO_ERROR)
164 return error;
165  
166 // read the RAM from the device to get the data
167 error = dallasReadRAM(rom_id, address, 2, data);
168  
169 // get the address for the setup for the channel
170 error = ds2450Chan2Addr(channel, DS2450_SETUP_PAGE, &address); //find starting address
171 if (error != DALLAS_NO_ERROR)
172 return error;
173  
174 // read the RAM from the device to get the resolution
175 error = dallasReadRAM(rom_id, address, 1, &resolution);
176 if (error != DALLAS_NO_ERROR)
177 return error;
178  
179 // get the resultion part of the data
180 resolution &=0x0F;
181  
182 // store the result by combining the 2 bytes
183 // the result's MSB is always the same, so we may need to
184 // shift the data over so that the LSB is at the first bit
185 *result = 0;
186 //*result = (((u16)data[1] << 8) | data[0]) >> (16 - resolution);
187 *result = (((u16)data[1] << 8) | data[0]);
188  
189 return DALLAS_NO_ERROR;
190 }
191  
192 u08 ds2450StartAndResult(dallas_rom_id_T* rom_id, u08 channel, u16 *result)
193 {
194 u08 error;
195  
196 // start conversion
197 error = ds2450Start(rom_id, channel);
198 if (error != DALLAS_NO_ERROR)
199 return error;
200  
201 // wait till conversion done
202 dallasWaitUntilDone();
203  
204 // return results
205 return ds2450Result(rom_id, channel, result);
206 }
207  
208 u08 ds2450SetupAll(dallas_rom_id_T* rom_id, u08 resolution, u08 range)
209 {
210 u08 i;
211 u08 error;
212 u08 data[8];
213 u16 address;
214  
215 // check address
216 error = dallasAddressCheck(rom_id, DS2450_FAMILY);
217 if (error != DALLAS_NO_ERROR)
218 return error;
219  
220 // check resolution
221 if (resolution > DS2450_RES_MAX)
222 return DALLAS_RESOLUTION_ERROR;
223  
224 // convert to valid resolution - 16 bits = 0x00
225 if (resolution == 16)
226 resolution = 0;
227  
228 // get address - start with channel A
229 error = ds2450Chan2Addr('A', DS2450_SETUP_PAGE, &address);
230 if (error != DALLAS_NO_ERROR)
231 return error;
232  
233 // read in current settings so we can extract digital part
234 error = dallasReadRAM(rom_id, address, 8, data);
235 if (error != DALLAS_NO_ERROR)
236 return error;
237  
238 // build up config data to write - increment by 2 b/c two bytes per channel
239 for(i=0;i<8;i+= 2)
240 {
241 // maintain digital output settings
242 data[i] &= 0xF0; // extract digital output portion
243 data[i+1] &= 0xFE;
244  
245 // write resolution byte and range
246 data[i] |= resolution;
247 data[i+1] |= range;
248 }
249  
250 // actually write config - handles CRC too
251 error = dallasWriteRAM(rom_id, address, 8, data);
252 if (error != DALLAS_NO_ERROR)
253 return error;
254  
255 // Normally, the DS2450 is designed to run off of parasite power from the data line
256 // Typically the master (us) strongly pulls high long enough to power the conversion, so
257 // there is inherintly a long () delay introduced. Since the A2D code is designed to
258 // work for devices that use external power, we can elliminate this delay by writting
259 // the following byte per the DS2450 datasheet.
260 data[0] = DS2450_VCC_FLAG;
261 error = dallasWriteRAM(rom_id, DS2450_VCC_ADDR, 1, &data[0]);
262 if (error != DALLAS_NO_ERROR)
263 return error;
264  
265 error = dallasReadRAM(rom_id,address,8,data);
266 if (error != DALLAS_NO_ERROR)
267 return error;
268  
269 for(i=0;i<8;i+=2)
270 {
271 if ((data[i] & 0x0F) != resolution)
272 return DALLAS_VERIFY_ERROR;
273 if ((data[i+1] & 0x01) != range)
274 return DALLAS_VERIFY_ERROR;
275 }
276  
277 return DALLAS_NO_ERROR;
278 }
279  
280 u08 ds2450StartAll(dallas_rom_id_T* rom_id)
281 {
282 u08 error;
283 u16 crc;
284  
285 // check address
286 error = dallasAddressCheck(rom_id, DS2450_FAMILY);
287 if (error != DALLAS_NO_ERROR)
288 return error;
289  
290 // reset and select node
291 error = dallasMatchROM(rom_id);
292 if (error != DALLAS_NO_ERROR)
293 return error;
294  
295 dallasWriteByte(DS2450_CONVERT); // send convert command
296 dallasWriteByte(DS2450_CONVERT_ALL4_MASK); // select all 4 inputs
297 dallasWriteByte(DS2450_CLEAR_ALL4_MASK); // set all output buffers to zero
298  
299 // we must read 2byte CRC16 to start the conversion:
300 crc = dallasReadByte() | ((u16)dallasReadByte() << 8);
301  
302 // replace with explicit CRC posibilities lookup table
303 // if (crc == 0xFFFF)
304 // return DALLAS_DEVICE_ERROR; // if CRC = all one's, no one is paying attention
305  
306 return DALLAS_NO_ERROR;
307 }
308  
309 u08 ds2450ResultAll(dallas_rom_id_T* rom_id, u16 result[4])
310 {
311 //const u08 bytes_to_read = 10; // read 10bytes = 2/ch*4ch + CRC
312 u08 bytes_to_read = 10;
313 u08 i;
314 u08 error;
315 u08 data[10];
316 u08 resolution[10];
317 u16 address;
318  
319 // check address
320  
321 error = dallasAddressCheck(rom_id, DS2450_FAMILY);
322 if (error != DALLAS_NO_ERROR)
323 return error;
324  
325 // start address with channel A
326 error = ds2450Chan2Addr('A', DS2450_DATA_PAGE, &address);
327 if (error != DALLAS_NO_ERROR)
328 return error;
329  
330 // read the conversion data
331 error = dallasReadRAM(rom_id, address, bytes_to_read, data);
332 if (error != DALLAS_NO_ERROR)
333 return error;
334  
335 //FUTURE: do a real CRC16 check
336  
337 // start address with channel A
338 error = ds2450Chan2Addr('A', DS2450_SETUP_PAGE, &address);
339 if (error != DALLAS_NO_ERROR)
340 return error;
341  
342 // read the resolution data
343 error = dallasReadRAM(rom_id, address, bytes_to_read, resolution);
344 if (error != DALLAS_NO_ERROR)
345 return error;
346  
347 // check crc?
348  
349 // store the result by combining the 2 bytes
350 // the result's MSB is always the same, so we may need to
351 // shift the data over so that the LSB is at the first bit
352 error=0;
353 for(i=0;i<8;i+=2)
354 {
355 resolution[i] &= 0x0F;
356 if (!resolution[i])
357 resolution[i] = 16;
358  
359 result[error] = 0;
360 //result[error] = (((u16)data[i+1] << 8) | data[i]) >> (16 - resolution[i]);
361 result[error] = (((u16)data[i+1] << 8) | data[i]);
362 error++;
363 }
364  
365 return DALLAS_NO_ERROR;
366 }
367  
368 u08 ds2450StartAndResultAll(dallas_rom_id_T* rom_id, u16 result[4])
369 {
370 u08 error;
371  
372 // start Conversion
373 error = ds2450StartAll(rom_id);
374 if (error != DALLAS_NO_ERROR)
375 return error;
376  
377 // wait until conversion done
378 dallasWaitUntilDone();
379  
380 // return any error - results passed by reference
381 return ds2450ResultAll(rom_id, result);
382 }
383  
384 void ds2450Print(u16 result, u08 range)
385 {
386 u16 vscale;
387  
388 rprintfProgStrM(" 0x");
389 rprintfu16(result);
390 rprintf(" ");
391 if(range)
392 vscale = 12800;
393 else
394 vscale = 25600;
395  
396 rprintfNum(10, 4, TRUE , ' ', result/vscale);
397 rprintf(".");
398 rprintfNum(10, 4, FALSE, '0', (((u32)(result%vscale))*10000)/vscale );
399 rprintfProgStrM(" Volts");
400 }
401  
402 u08 ds2450DigitalOut(dallas_rom_id_T* rom_id, u08 channel, dallas_a2d_out_T state)
403 {
404 u08 error;
405 u08 old_resolution;
406 u16 address;
407  
408 // check address
409 error = dallasAddressCheck(rom_id, DS2450_FAMILY);
410 if (error != DALLAS_NO_ERROR)
411 return error;
412  
413 // get the address for the channel in the setup page
414 error = ds2450Chan2Addr(channel, DS2450_SETUP_PAGE, &address);
415 if (error != DALLAS_NO_ERROR)
416 return error;
417  
418 // read in current resolution
419 error = dallasReadRAM(rom_id, address, 1, &old_resolution);
420 if (error != DALLAS_NO_ERROR)
421 return error;
422  
423 // extract resolution portion
424 old_resolution &= 0x0F;
425  
426 // write new setup byte
427 state |= old_resolution;
428 error = dallasWriteRAM(rom_id, address, 1, ((u08*)&state));
429 if (error != DALLAS_NO_ERROR)
430 return error;
431  
432 return DALLAS_NO_ERROR;
433 }
434  
435 static u08 ds2450Chan2Addr(u08 channel, u08 page, u16 *address)
436 {
437 // make sure the channel is a capital letter
438 strupr(&channel);
439  
440 //convert to integer 0 to 3 and check to see if it is valid
441 channel -= 'A';
442 if (channel > 3)
443 return DALLAS_INVALID_CHANNEL;
444  
445 // use corresponding memory address
446 *address = (channel<<1) + page; // channel<<1 == channel*2, but faster
447  
448 return DALLAS_NO_ERROR;
449 }
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3