Dallas 1-wire driver with DS18B20 temperature sensor support; custom bus driver to work with https://emir.googlecode.com/svn/emir2/trunk/eagle/emir-shield.sch
Dependents: testing_RTC_OneWire EMIRv2
1wire.cpp
00001 #include "mbed.h" 00002 #include "1wire.h" 00003 00004 OneWire::OneWire(PinName OwUp, PinName OwDn, PinName OwIn) : _OwUp(OwUp, !0), _OwDn(OwDn, !1), _OwIn(OwIn, PullNone) 00005 { 00006 } 00007 00008 int OneWire::Reset(void) 00009 { 00010 int result; 00011 00012 DELAY_G(); 00013 __disable_irq(); 00014 _OwDn = !0; 00015 DELAY_H(); 00016 _OwDn = !1; 00017 DELAY_I(); 00018 result = _OwIn; 00019 __enable_irq(); 00020 DELAY_J(); 00021 return result; 00022 } 00023 00024 void OneWire::WriteBit(int bit) 00025 { 00026 __disable_irq(); 00027 if (bit) { 00028 _OwDn = !0; 00029 DELAY_A(); 00030 _OwDn = !1; 00031 DELAY_B(); 00032 } else { 00033 _OwDn = !0; 00034 DELAY_C(); 00035 _OwDn = !1; 00036 DELAY_D(); 00037 } 00038 __enable_irq(); 00039 } 00040 00041 int OneWire::ReadBit(void) 00042 { 00043 int result; 00044 00045 __disable_irq(); 00046 _OwDn = !0; 00047 DELAY_A(); 00048 _OwDn = !1; 00049 DELAY_E(); 00050 result = _OwIn; 00051 __enable_irq(); 00052 DELAY_F(); 00053 return result; 00054 } 00055 00056 void OneWire::WriteByte(uint8_t data) 00057 { 00058 for (int i = 0; i < 8; i++) { 00059 WriteBit(data & 0x01); 00060 data >>= 1; 00061 } 00062 } 00063 00064 uint8_t OneWire::ReadByte(void) 00065 { 00066 uint8_t result = 0; 00067 00068 for (int i = 0; i < 8; i++) { 00069 result >>= 1; 00070 if (ReadBit()) 00071 result |= 0x80; 00072 } 00073 return result; 00074 } 00075 00076 void OneWire::SendCmd(uint8_t *ROMID, uint8_t cmd) 00077 { 00078 Reset(); 00079 if (ROMID == NULL) { 00080 WriteByte(OW_SKIP_ROM_CMD); 00081 } else { 00082 WriteByte(OW_MATCH_ROM_CMD); 00083 for (int i = 0; i < 8; i++) 00084 WriteByte(ROMID[i]); 00085 } 00086 WriteByte(cmd); 00087 } 00088 00089 int OneWire::First(uint8_t *ROMID) 00090 { 00091 /* Reset state */ 00092 OW_LastDiscrepancy = 0; 00093 OW_LastDevice = 0; 00094 OW_LastFamilyDiscrepancy = 0; 00095 00096 /* Go looking */ 00097 return Next(ROMID); 00098 } 00099 00100 int OneWire::Next(uint8_t *ROMID) 00101 { 00102 uint8_t bit_test, search_direction, bit_number; 00103 uint8_t last_zero, rom_byte_number, rom_byte_mask; 00104 uint8_t lastcrc8, crcaccum; 00105 int next_result; 00106 00107 /* Init for search */ 00108 bit_number = 1; 00109 last_zero = 0; 00110 rom_byte_number = 0; 00111 rom_byte_mask = 1; 00112 next_result = OW_NOMODULES; 00113 lastcrc8 = 0; 00114 crcaccum = 0; 00115 00116 /* if the last call was not the last one */ 00117 if (!OW_LastDevice) { 00118 /* reset the 1-wire if there are no parts on 1-wire, return 0 */ 00119 if (Reset()) { 00120 /* reset the search */ 00121 OW_LastDiscrepancy = 0; 00122 OW_LastFamilyDiscrepancy = 0; 00123 return OW_NOPRESENCE; 00124 } 00125 00126 WriteByte(OW_SEARCH_ROM_CMD); /* issue the search command */ 00127 00128 /* pause before beginning the search - removed */ 00129 /* loop to do the search */ 00130 do { 00131 /* read a bit and its compliment */ 00132 bit_test = ReadBit() << 1; 00133 bit_test |= ReadBit(); 00134 00135 /* check for no devices on 1-wire */ 00136 if (bit_test == 3) { 00137 return(OW_BADWIRE); 00138 } else { 00139 /* all devices coupled have 0 or 1 */ 00140 if (bit_test > 0) 00141 search_direction = !(bit_test & 0x01); /* bit write value for search */ 00142 else { 00143 /* if this discrepancy is before the Last Discrepancy 00144 * on a previous OWNext then pick the same as last time */ 00145 if (bit_number < OW_LastDiscrepancy) 00146 search_direction = ((ROMID[rom_byte_number] & rom_byte_mask) > 0); 00147 else 00148 /* if equal to last pick 1, if not then pick 0 */ 00149 search_direction = (bit_number == OW_LastDiscrepancy); 00150 00151 /* if 0 was picked then record its position in LastZero */ 00152 if (search_direction == 0) { 00153 last_zero = bit_number; 00154 /* check for Last discrepancy in family */ 00155 if (last_zero < 9) 00156 OW_LastFamilyDiscrepancy = last_zero; 00157 } 00158 } 00159 00160 /* set or clear the bit in the ROM byte rom_byte_number 00161 * with mask rom_byte_mask */ 00162 if (search_direction == 1) 00163 ROMID[rom_byte_number] |= rom_byte_mask; 00164 else 00165 ROMID[rom_byte_number] &= ~rom_byte_mask; 00166 00167 /* serial number search direction write bit */ 00168 WriteBit(search_direction); 00169 00170 /* increment the byte counter bit_number 00171 * and shift the mask rom_byte_mask */ 00172 bit_number++; 00173 rom_byte_mask <<= 1; 00174 00175 /* if the mask is 0 then go to new ROM byte rom_byte_number 00176 * and reset mask */ 00177 if (rom_byte_mask == 0) { 00178 CRC(ROMID[rom_byte_number], &crcaccum); /* accumulate the CRC */ 00179 lastcrc8 = crcaccum; 00180 00181 rom_byte_number++; 00182 rom_byte_mask = 1; 00183 } 00184 } 00185 } while (rom_byte_number < 8); /* loop until through all ROM bytes 0-7 */ 00186 00187 /* if the search was successful then */ 00188 if (!(bit_number < 65) || lastcrc8) { 00189 if (lastcrc8) { 00190 next_result = OW_BADCRC; 00191 } else { 00192 /* search successful so set LastDiscrepancy,LastDevice,next_result */ 00193 OW_LastDiscrepancy = last_zero; 00194 OW_LastDevice = (OW_LastDiscrepancy == 0); 00195 next_result = OW_FOUND; 00196 } 00197 } 00198 } 00199 00200 /* if no device found then reset counters so next 'next' will be like a first */ 00201 if (next_result != OW_FOUND || ROMID[0] == 0) { 00202 OW_LastDiscrepancy = 0; 00203 OW_LastDevice = 0; 00204 OW_LastFamilyDiscrepancy = 0; 00205 } 00206 00207 if (next_result == OW_FOUND && ROMID[0] == 0x00) 00208 next_result = OW_BADWIRE; 00209 00210 return next_result; 00211 } 00212 00213 void OneWire::CRC(uint8_t x, uint8_t *crc) 00214 { 00215 for (int j = 0; j < 8; j++) { 00216 uint8_t mix = (*crc ^ x) & 0x01; 00217 *crc >>= 1; 00218 if (mix) *crc ^= 0x8C; 00219 x >>= 1; 00220 } 00221 } 00222 00223 void OneWire::ConvertAll(bool wait) 00224 { 00225 SendCmd(NULL, OW_CONVERT_T_CMD); 00226 if (wait) { 00227 _OwUp = !1; 00228 wait_ms(CONVERT_T_DELAY); 00229 _OwUp = !0; 00230 } 00231 } 00232 00233 int OneWire::ReadTemperature(uint8_t *ROMID, int *result) 00234 { 00235 uint8_t crc = 0, buf[8]; 00236 00237 SendCmd(ROMID, OW_RD_SCR_CMD); 00238 for (int i = 0; i < 8; i++) { 00239 buf[i] = ReadByte(); 00240 CRC(buf[i], &crc); 00241 } 00242 if (crc != ReadByte()) { 00243 return ERR_BADCRC; 00244 } 00245 00246 switch (ROMID[0]) { 00247 case 0x10: // ds18s20 00248 *result = (signed char)((buf[1] & 0x80) | (buf[0] >> 1)) * 100 + 75 - buf[6] * 100 / 16; 00249 break; 00250 case 0x28: // ds18b20 00251 *result = (signed char)((buf[1] << 4) | (buf[0] >> 4)) * 100 + (buf[0] & 0x0F) * 100 / 16; 00252 break; 00253 default: 00254 return ERR_BADFAMILY; 00255 } 00256 return 0; 00257 }
Generated on Tue Jul 12 2022 18:13:10 by 1.7.2