1 /* Dallas 1-Wire bus routines */
4 #include <xc.h> /* XC8 General Include File */
5 #elif defined(HI_TECH_C)
6 #include <htc.h> /* HiTech General Include File */
9 #include <stdint.h> /* For uint8_t definition */
10 #include <stdbool.h> /* For true/false definition */
17 #define OWLOW { PORTAbits.RA5 = 0; TRISAbits.TRISA5 = 0; }
18 #define OWHIGH { PORTAbits.RA5 = 1; TRISAbits.TRISA5 = 0; }
19 #define OWTRI { TRISAbits.TRISA5 = 1; }
20 #define OWREAD (PORTAbits.RA5)
23 // slow way, causes a function call
24 inline void drive_OW_low(void)
30 inline void drive_OW_high(void)
36 inline void float_OW(void)
41 inline bool read_OW(void)
48 /* start the 1-Wire bus
57 /* reset the bus, test for presence signal */
62 OWLOW; //drive_OW_low();
65 OWTRI; //float_OW(); // let it float high
67 presence = OWREAD; //read_OW(); // now sample
74 void OW_write_bit(bool val)
76 #if 0 // Maxim dev note 2420
87 // NOP(); // doc one for other delays
99 #if 0 /* Maxim dev note 2420 */
126 void OW_write_byte(unsigned char byte)
128 for (char i=8; i!=0; i--)
130 OW_write_bit( byte & 0x01 );
135 unsigned char OW_read_byte(void)
137 unsigned char byte = 0;
138 for (char i=8; i!=0; i--)
148 static const unsigned char dscrc_table[] = {
149 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
150 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
151 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
152 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
153 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
154 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
155 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
156 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
157 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
158 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
159 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
160 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
161 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
162 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
163 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
164 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53
167 unsigned char romid[8];
168 char LastDiscrepancy = 0;
169 char LastFamilyDiscrepancy = 0;
170 char LastDeviceFlag = false;
173 static unsigned char docrc8(unsigned char value)
175 crc8 = dscrc_table[crc8 ^ value];
179 /* enumerate the devices */
182 char id_bit_number = 1;
184 char rom_byte_number = 0;
185 char search_result = 0;
186 unsigned char rom_byte_mask = 1;
187 unsigned char search_direction;
191 // do not interrupt us
194 // if the last call was not the last one
195 if (!LastDeviceFlag) {
198 msg_write("Reset said nothing there.\r\n");
202 LastFamilyDiscrepancy = 0;
207 // issue the search command
210 // loop to do the search
212 // read a bit and its complement
213 bool id_bit = OW_read_bit();
215 bool cmp_id_bit = OW_read_bit();
217 // check for no devices on bus
218 if (id_bit && cmp_id_bit) {
222 if (id_bit != cmp_id_bit) {
223 // all devices have a 0 here, or they all have a 1
224 search_direction = id_bit;
226 // both bits zero, so both 0 and 1 exist
228 // if this discrepancy is before the Last Discrepancy
229 // on a previous next then pick the same as last time
230 if (id_bit_number < LastDiscrepancy) {
231 search_direction = ((romid[rom_byte_number] & rom_byte_mask) > 0);
233 // if equal to last pick 1, if not then pick 0
234 search_direction = (id_bit_number == LastDiscrepancy);
237 // if 0 was picked then record its position in LastZero
238 if (search_direction == 0)
240 last_zero = id_bit_number;
241 // check for last discrepancy in family
243 LastFamilyDiscrepancy = last_zero;
247 // set or clear the bit in the ROM byte rom_byte_number
248 // with mask rom_byte_mask
249 if (search_direction == 1)
250 romid[rom_byte_number] |= rom_byte_mask;
252 romid[rom_byte_number] &= ~rom_byte_mask;
254 // serial number search direction write bit
255 OW_write_bit(search_direction);
257 // increment the byte counter id_bit_number
258 // and shift the mask rom_byte_mask
262 // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
263 if (rom_byte_mask == 0)
265 docrc8(romid[rom_byte_number]); // accumulate the CRC
269 } while (rom_byte_number < 8); // loop until all rom bytes 0-7
270 } // end of not-last-device
272 // if the search was succesful then
273 if (!(id_bit_number < 65 || crc8 != 0))
276 LastDiscrepancy = last_zero;
278 // check for last device
279 if (LastDiscrepancy == 0)
280 LastDeviceFlag = true;
282 search_result = true;
285 if (!search_result || !romid[0])
288 LastDeviceFlag = false;
289 LastFamilyDiscrepancy = 0;
290 search_result = false;
294 return search_result;
298 void OW_search_init()
301 LastDeviceFlag = false;
302 LastFamilyDiscrepancy = 0;
304 for (int j=0; j<8; j++) romid[j]=0;
308 /* ask the (lone) device for its Serial number */
315 for (int j=0; j<8; j++)
316 romid[j] = OW_read_byte();
320 /* is anyone parasite powered ? */
321 bool OW_parasite(void)
325 OW_write_byte(0xCC); // skip the rom command
326 OW_write_byte(0xB4); // are you parasite powered ?
327 bool no = OW_read_bit();
332 /* select a specific device,
333 * if family==0 select all devices (skip rom)
335 static void OW_select_id(void)
338 OW_write_byte(0xCC); // all devices for now
340 OW_write_byte(0x55); // match rom
341 for (int8_t j=0; j<8; j++) {
342 OW_write_byte(romid[j]);
348 /* read a memory block eg scratchpad 0xBE */
349 void OW_read_block(uint8_t code, uint8_t * data, uint8_t len)
355 for (int8_t j=0; j<len; j++)
356 data[j] = OW_read_byte();
360 /* write a memory block to device, eg scratchpad 0x4E */
361 void OW_write_block(uint8_t code, uint8_t * data, uint8_t len)
367 for (int8_t j=0; j<len; j++) {
368 OW_write_byte(data[j]);
374 // perform temperature conversion
377 // first see if anyone is parasitic
378 bool para = OW_parasite();
381 OW_reset(); // all command start with reset
383 //OW_write_byte(0xCC); // all devices
384 OW_write_byte(0x44); // convert
386 // hard high for 750mS
393 // keep polling until its done
394 // device will reply with 0 'pull low' whilst convert in progress
397 } while (!OW_read_bit());
402 /* Available commands :-
403 * 33h - read rom (sends 8 bytes)
404 * 55h - match rom (reads 8 bytes)
405 * F0h - search rom (enumeration mode)
407 * CC - skip rom command
410 * 44h - convert temperature
411 * 48h - copy scratchpad -> eeprom
412 * 4Eh - write scratchpad (send 3 bytes )
413 * BEh - read scratchpad ( 8 bytes + crc)
414 * B8h - recall EEPROM -> scratchpad
415 * B4h - read power supply (read 1 bit)