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

Powered by WebSVN v2.8.3