Implementation of 1-Wire with added Alarm Search Functionality

Dependents:   Max32630_One_Wire_Interface

Committer:
IanBenzMaxim
Date:
Mon May 16 10:36:30 2016 -0500
Revision:
77:529edb329ee0
Parent:
76:84e6c4994e29
Child:
78:0cbbac7f2016
Added iterators for selecting 1-Wire devices on the bus and added support iterator support to OneWireSlave class.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
j3 5:ce108eeb878d 1 /******************************************************************//**
j3 5:ce108eeb878d 2 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
j3 5:ce108eeb878d 3 *
j3 5:ce108eeb878d 4 * Permission is hereby granted, free of charge, to any person obtaining a
j3 5:ce108eeb878d 5 * copy of this software and associated documentation files (the "Software"),
j3 5:ce108eeb878d 6 * to deal in the Software without restriction, including without limitation
j3 5:ce108eeb878d 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
j3 5:ce108eeb878d 8 * and/or sell copies of the Software, and to permit persons to whom the
j3 5:ce108eeb878d 9 * Software is furnished to do so, subject to the following conditions:
j3 5:ce108eeb878d 10 *
j3 5:ce108eeb878d 11 * The above copyright notice and this permission notice shall be included
j3 5:ce108eeb878d 12 * in all copies or substantial portions of the Software.
j3 5:ce108eeb878d 13 *
j3 5:ce108eeb878d 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
j3 5:ce108eeb878d 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
j3 5:ce108eeb878d 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
j3 5:ce108eeb878d 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
j3 5:ce108eeb878d 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
j3 5:ce108eeb878d 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
j3 5:ce108eeb878d 20 * OTHER DEALINGS IN THE SOFTWARE.
j3 5:ce108eeb878d 21 *
j3 5:ce108eeb878d 22 * Except as contained in this notice, the name of Maxim Integrated
j3 5:ce108eeb878d 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
j3 5:ce108eeb878d 24 * Products, Inc. Branding Policy.
j3 5:ce108eeb878d 25 *
j3 5:ce108eeb878d 26 * The mere transfer of this software does not imply any licenses
j3 5:ce108eeb878d 27 * of trade secrets, proprietary technology, copyrights, patents,
j3 5:ce108eeb878d 28 * trademarks, maskwork rights, or any other form of intellectual
j3 5:ce108eeb878d 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
j3 5:ce108eeb878d 30 * ownership rights.
j3 5:ce108eeb878d 31 **********************************************************************/
j3 5:ce108eeb878d 32
j3 15:f6cb0d906fb6 33 #include "OneWireMaster.h"
IanBenzMaxim 73:2cecc1372acc 34 #include "RomId.h"
IanBenzMaxim 27:d5aaefa252f1 35
IanBenzMaxim 76:84e6c4994e29 36 using OneWire::OneWireMaster;
j3 15:f6cb0d906fb6 37
IanBenzMaxim 77:529edb329ee0 38 enum OwRomCmd
IanBenzMaxim 77:529edb329ee0 39 {
IanBenzMaxim 77:529edb329ee0 40 ReadRomCmd = 0x33,
IanBenzMaxim 77:529edb329ee0 41 MatchRomCmd = 0x55,
IanBenzMaxim 77:529edb329ee0 42 SearchRomCmd = 0xF0,
IanBenzMaxim 77:529edb329ee0 43 SkipRomCmd = 0xCC,
IanBenzMaxim 77:529edb329ee0 44 ResumeCmd = 0xA5,
IanBenzMaxim 77:529edb329ee0 45 OverdriveSkipRomCmd = 0x3C,
IanBenzMaxim 77:529edb329ee0 46 OverdriveMatchRomCmd = 0x69
IanBenzMaxim 77:529edb329ee0 47 };
IanBenzMaxim 77:529edb329ee0 48
IanBenzMaxim 75:8b627804927c 49 OneWireMaster::CmdResult OneWireMaster::OWWriteBlock(const uint8_t *sendBuf, uint8_t sendLen)
IanBenzMaxim 71:562f5c702094 50 {
IanBenzMaxim 71:562f5c702094 51 CmdResult result;
IanBenzMaxim 74:23be10c32fa3 52
IanBenzMaxim 75:8b627804927c 53 for (uint8_t idx = 0; idx < sendLen; idx++)
IanBenzMaxim 71:562f5c702094 54 {
IanBenzMaxim 75:8b627804927c 55 result = OWWriteByte(sendBuf[idx]);
IanBenzMaxim 74:23be10c32fa3 56 if (result != Success)
IanBenzMaxim 71:562f5c702094 57 {
IanBenzMaxim 71:562f5c702094 58 break;
IanBenzMaxim 71:562f5c702094 59 }
IanBenzMaxim 71:562f5c702094 60 }
IanBenzMaxim 74:23be10c32fa3 61
IanBenzMaxim 71:562f5c702094 62 return result;
IanBenzMaxim 71:562f5c702094 63 }
IanBenzMaxim 71:562f5c702094 64
IanBenzMaxim 75:8b627804927c 65 OneWireMaster::CmdResult OneWireMaster::OWReadBlock(uint8_t *recvBuf, uint8_t recvLen)
IanBenzMaxim 71:562f5c702094 66 {
IanBenzMaxim 71:562f5c702094 67 CmdResult result;
IanBenzMaxim 74:23be10c32fa3 68
IanBenzMaxim 75:8b627804927c 69 for (uint8_t idx = 0; idx < recvLen; idx++)
IanBenzMaxim 71:562f5c702094 70 {
IanBenzMaxim 75:8b627804927c 71 result = OWReadByte(recvBuf[idx]);
IanBenzMaxim 74:23be10c32fa3 72 if (result != Success)
IanBenzMaxim 71:562f5c702094 73 {
IanBenzMaxim 71:562f5c702094 74 break;
IanBenzMaxim 71:562f5c702094 75 }
IanBenzMaxim 71:562f5c702094 76 }
IanBenzMaxim 74:23be10c32fa3 77
IanBenzMaxim 71:562f5c702094 78 return result;
IanBenzMaxim 71:562f5c702094 79 }
IanBenzMaxim 71:562f5c702094 80
IanBenzMaxim 75:8b627804927c 81 OneWireMaster::CmdResult OneWireMaster::OWTriplet(SearchDirection & searchDirection, uint8_t & sbr, uint8_t & tsb)
IanBenzMaxim 32:bce180b544ed 82 {
IanBenzMaxim 32:bce180b544ed 83 CmdResult result;
IanBenzMaxim 32:bce180b544ed 84 result = OWReadBit(sbr);
IanBenzMaxim 32:bce180b544ed 85 if (result == Success)
IanBenzMaxim 74:23be10c32fa3 86 {
IanBenzMaxim 32:bce180b544ed 87 result = OWReadBit(tsb);
IanBenzMaxim 74:23be10c32fa3 88 }
IanBenzMaxim 32:bce180b544ed 89 if (result == Success)
IanBenzMaxim 32:bce180b544ed 90 {
IanBenzMaxim 57:1635f247ceae 91 if (sbr)
IanBenzMaxim 74:23be10c32fa3 92 {
IanBenzMaxim 75:8b627804927c 93 searchDirection = WriteOne;
IanBenzMaxim 74:23be10c32fa3 94 }
IanBenzMaxim 57:1635f247ceae 95 else if (tsb)
IanBenzMaxim 74:23be10c32fa3 96 {
IanBenzMaxim 75:8b627804927c 97 searchDirection = WriteZero;
IanBenzMaxim 74:23be10c32fa3 98 }
IanBenzMaxim 32:bce180b544ed 99 // else: use search_direction parameter
IanBenzMaxim 74:23be10c32fa3 100
IanBenzMaxim 75:8b627804927c 101 result = OWWriteBit((searchDirection == WriteOne) ? 1 : 0);
IanBenzMaxim 32:bce180b544ed 102 }
IanBenzMaxim 32:bce180b544ed 103 return result;
IanBenzMaxim 32:bce180b544ed 104 }
IanBenzMaxim 32:bce180b544ed 105
IanBenzMaxim 75:8b627804927c 106 uint16_t OneWireMaster::calculateCrc16(uint16_t crc16, uint16_t data)
j3 15:f6cb0d906fb6 107 {
IanBenzMaxim 75:8b627804927c 108 const uint16_t oddparity[] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
IanBenzMaxim 74:23be10c32fa3 109
IanBenzMaxim 75:8b627804927c 110 data = (data ^ (crc16 & 0xff)) & 0xff;
IanBenzMaxim 75:8b627804927c 111 crc16 >>= 8;
j3 17:b646b1e3970b 112
IanBenzMaxim 75:8b627804927c 113 if (oddparity[data & 0xf] ^ oddparity[data >> 4])
IanBenzMaxim 74:23be10c32fa3 114 {
IanBenzMaxim 75:8b627804927c 115 crc16 ^= 0xc001;
IanBenzMaxim 74:23be10c32fa3 116 }
j3 17:b646b1e3970b 117
IanBenzMaxim 74:23be10c32fa3 118 data <<= 6;
IanBenzMaxim 75:8b627804927c 119 crc16 ^= data;
IanBenzMaxim 74:23be10c32fa3 120 data <<= 1;
IanBenzMaxim 75:8b627804927c 121 crc16 ^= data;
j3 17:b646b1e3970b 122
IanBenzMaxim 75:8b627804927c 123 return crc16;
j3 15:f6cb0d906fb6 124 }
j3 15:f6cb0d906fb6 125
IanBenzMaxim 75:8b627804927c 126 uint16_t OneWireMaster::calculateCrc16(const uint8_t * data, size_t dataOffset, size_t dataLen, uint16_t crc)
IanBenzMaxim 74:23be10c32fa3 127 {
IanBenzMaxim 75:8b627804927c 128 for (size_t i = dataOffset; i < (dataLen + dataOffset); i++)
IanBenzMaxim 74:23be10c32fa3 129 {
IanBenzMaxim 75:8b627804927c 130 crc = calculateCrc16(crc, data[i]);
IanBenzMaxim 74:23be10c32fa3 131 }
IanBenzMaxim 74:23be10c32fa3 132 return crc;
IanBenzMaxim 48:6f9208ae280e 133 }
IanBenzMaxim 77:529edb329ee0 134
IanBenzMaxim 77:529edb329ee0 135 void OneWireMaster::SearchState::reset()
IanBenzMaxim 77:529edb329ee0 136 {
IanBenzMaxim 77:529edb329ee0 137 last_discrepancy = 0;
IanBenzMaxim 77:529edb329ee0 138 last_device_flag = false;
IanBenzMaxim 77:529edb329ee0 139 last_family_discrepancy = 0;
IanBenzMaxim 77:529edb329ee0 140 romId.reset();
IanBenzMaxim 77:529edb329ee0 141 }
IanBenzMaxim 77:529edb329ee0 142
IanBenzMaxim 77:529edb329ee0 143 void OneWireMaster::SearchState::findFamily(uint8_t familyCode)
IanBenzMaxim 77:529edb329ee0 144 {
IanBenzMaxim 77:529edb329ee0 145 reset();
IanBenzMaxim 77:529edb329ee0 146 romId.setFamilyCode(familyCode);
IanBenzMaxim 77:529edb329ee0 147 last_discrepancy = 64;
IanBenzMaxim 77:529edb329ee0 148 }
IanBenzMaxim 77:529edb329ee0 149
IanBenzMaxim 77:529edb329ee0 150 void OneWireMaster::SearchState::skipCurrentFamily()
IanBenzMaxim 77:529edb329ee0 151 {
IanBenzMaxim 77:529edb329ee0 152 // set the Last discrepancy to last family discrepancy
IanBenzMaxim 77:529edb329ee0 153 last_discrepancy = last_family_discrepancy;
IanBenzMaxim 77:529edb329ee0 154
IanBenzMaxim 77:529edb329ee0 155 // clear the last family discrpepancy
IanBenzMaxim 77:529edb329ee0 156 last_family_discrepancy = 0;
IanBenzMaxim 77:529edb329ee0 157
IanBenzMaxim 77:529edb329ee0 158 // check for end of list
IanBenzMaxim 77:529edb329ee0 159 if (last_discrepancy == 0)
IanBenzMaxim 77:529edb329ee0 160 {
IanBenzMaxim 77:529edb329ee0 161 last_device_flag = true;
IanBenzMaxim 77:529edb329ee0 162 }
IanBenzMaxim 77:529edb329ee0 163 }
IanBenzMaxim 77:529edb329ee0 164
IanBenzMaxim 77:529edb329ee0 165 OneWireMaster::CmdResult OneWireMaster::OWFirst(SearchState & searchState)
IanBenzMaxim 77:529edb329ee0 166 {
IanBenzMaxim 77:529edb329ee0 167 // Reset and begin a new search
IanBenzMaxim 77:529edb329ee0 168 searchState.reset();
IanBenzMaxim 77:529edb329ee0 169 return OWSearch(searchState);
IanBenzMaxim 77:529edb329ee0 170 }
IanBenzMaxim 77:529edb329ee0 171
IanBenzMaxim 77:529edb329ee0 172 OneWireMaster::CmdResult OneWireMaster::OWNext(SearchState & searchState)
IanBenzMaxim 77:529edb329ee0 173 {
IanBenzMaxim 77:529edb329ee0 174 // Continue the previous search
IanBenzMaxim 77:529edb329ee0 175 return OWSearch(searchState);
IanBenzMaxim 77:529edb329ee0 176 }
IanBenzMaxim 77:529edb329ee0 177
IanBenzMaxim 77:529edb329ee0 178 OneWireMaster::CmdResult OneWireMaster::OWVerify(const RomId & romId)
IanBenzMaxim 77:529edb329ee0 179 {
IanBenzMaxim 77:529edb329ee0 180 OneWireMaster::CmdResult result;
IanBenzMaxim 77:529edb329ee0 181 SearchState searchState;
IanBenzMaxim 77:529edb329ee0 182
IanBenzMaxim 77:529edb329ee0 183 searchState.romId = romId;
IanBenzMaxim 77:529edb329ee0 184
IanBenzMaxim 77:529edb329ee0 185 // set search to find the same device
IanBenzMaxim 77:529edb329ee0 186 searchState.last_discrepancy = 64;
IanBenzMaxim 77:529edb329ee0 187 searchState.last_device_flag = false;
IanBenzMaxim 77:529edb329ee0 188
IanBenzMaxim 77:529edb329ee0 189 result = OWSearch(searchState);
IanBenzMaxim 77:529edb329ee0 190 if (result == OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 191 {
IanBenzMaxim 77:529edb329ee0 192 // check if same device found
IanBenzMaxim 77:529edb329ee0 193 if (romId != searchState.romId)
IanBenzMaxim 77:529edb329ee0 194 {
IanBenzMaxim 77:529edb329ee0 195 result = OneWireMaster::OperationFailure;
IanBenzMaxim 77:529edb329ee0 196 }
IanBenzMaxim 77:529edb329ee0 197 }
IanBenzMaxim 77:529edb329ee0 198
IanBenzMaxim 77:529edb329ee0 199 return result;
IanBenzMaxim 77:529edb329ee0 200 }
IanBenzMaxim 77:529edb329ee0 201
IanBenzMaxim 77:529edb329ee0 202 OneWireMaster::CmdResult OneWireMaster::OWReadRom(RomId & romId)
IanBenzMaxim 77:529edb329ee0 203 {
IanBenzMaxim 77:529edb329ee0 204 OneWireMaster::CmdResult result;
IanBenzMaxim 77:529edb329ee0 205 RomId readId;
IanBenzMaxim 77:529edb329ee0 206
IanBenzMaxim 77:529edb329ee0 207 result = OWReset();
IanBenzMaxim 77:529edb329ee0 208 if (result == OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 209 {
IanBenzMaxim 77:529edb329ee0 210 result = OWWriteByte(ReadRomCmd);
IanBenzMaxim 77:529edb329ee0 211 }
IanBenzMaxim 77:529edb329ee0 212
IanBenzMaxim 77:529edb329ee0 213 // read the ROM
IanBenzMaxim 77:529edb329ee0 214 if (result == OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 215 {
IanBenzMaxim 77:529edb329ee0 216 result = OWReadBlock(readId, RomId::byteLen);
IanBenzMaxim 77:529edb329ee0 217 }
IanBenzMaxim 77:529edb329ee0 218
IanBenzMaxim 77:529edb329ee0 219 // verify CRC8
IanBenzMaxim 77:529edb329ee0 220 if (result == OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 221 {
IanBenzMaxim 77:529edb329ee0 222 if (readId.crc8Valid())
IanBenzMaxim 77:529edb329ee0 223 {
IanBenzMaxim 77:529edb329ee0 224 romId = readId;
IanBenzMaxim 77:529edb329ee0 225 }
IanBenzMaxim 77:529edb329ee0 226 else
IanBenzMaxim 77:529edb329ee0 227 {
IanBenzMaxim 77:529edb329ee0 228 result = OneWireMaster::OperationFailure;
IanBenzMaxim 77:529edb329ee0 229 }
IanBenzMaxim 77:529edb329ee0 230 }
IanBenzMaxim 77:529edb329ee0 231
IanBenzMaxim 77:529edb329ee0 232 return result;
IanBenzMaxim 77:529edb329ee0 233 }
IanBenzMaxim 77:529edb329ee0 234
IanBenzMaxim 77:529edb329ee0 235 OneWireMaster::CmdResult OneWireMaster::OWSkipRom()
IanBenzMaxim 77:529edb329ee0 236 {
IanBenzMaxim 77:529edb329ee0 237 OneWireMaster::CmdResult result;
IanBenzMaxim 77:529edb329ee0 238
IanBenzMaxim 77:529edb329ee0 239 result = OWReset();
IanBenzMaxim 77:529edb329ee0 240 if (result == OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 241 {
IanBenzMaxim 77:529edb329ee0 242 result = OWWriteByte(SkipRomCmd);
IanBenzMaxim 77:529edb329ee0 243 }
IanBenzMaxim 77:529edb329ee0 244
IanBenzMaxim 77:529edb329ee0 245 return result;
IanBenzMaxim 77:529edb329ee0 246 }
IanBenzMaxim 77:529edb329ee0 247
IanBenzMaxim 77:529edb329ee0 248 OneWireMaster::CmdResult OneWireMaster::OWMatchRom(const RomId & romId)
IanBenzMaxim 77:529edb329ee0 249 {
IanBenzMaxim 77:529edb329ee0 250 OneWireMaster::CmdResult result;
IanBenzMaxim 77:529edb329ee0 251
IanBenzMaxim 77:529edb329ee0 252 uint8_t buf[1 + RomId::byteLen];
IanBenzMaxim 77:529edb329ee0 253
IanBenzMaxim 77:529edb329ee0 254 // use MatchROM
IanBenzMaxim 77:529edb329ee0 255 result = OWReset();
IanBenzMaxim 77:529edb329ee0 256 if (result == OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 257 {
IanBenzMaxim 77:529edb329ee0 258 buf[0] = MatchRomCmd;
IanBenzMaxim 77:529edb329ee0 259 std::memcpy(&buf[1], romId, RomId::byteLen);
IanBenzMaxim 77:529edb329ee0 260 // send command and rom
IanBenzMaxim 77:529edb329ee0 261 result = OWWriteBlock(buf, 1 + RomId::byteLen);
IanBenzMaxim 77:529edb329ee0 262 }
IanBenzMaxim 77:529edb329ee0 263
IanBenzMaxim 77:529edb329ee0 264 return result;
IanBenzMaxim 77:529edb329ee0 265 }
IanBenzMaxim 77:529edb329ee0 266
IanBenzMaxim 77:529edb329ee0 267 OneWireMaster::CmdResult OneWireMaster::OWOverdriveSkipRom()
IanBenzMaxim 77:529edb329ee0 268 {
IanBenzMaxim 77:529edb329ee0 269 OneWireMaster::CmdResult result = OWSetSpeed(OneWireMaster::StandardSpeed);
IanBenzMaxim 77:529edb329ee0 270
IanBenzMaxim 77:529edb329ee0 271 if (result == OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 272 {
IanBenzMaxim 77:529edb329ee0 273 result = OWReset();
IanBenzMaxim 77:529edb329ee0 274 }
IanBenzMaxim 77:529edb329ee0 275
IanBenzMaxim 77:529edb329ee0 276 if (result == OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 277 {
IanBenzMaxim 77:529edb329ee0 278 result = OWWriteByte(OverdriveSkipRomCmd);
IanBenzMaxim 77:529edb329ee0 279 }
IanBenzMaxim 77:529edb329ee0 280
IanBenzMaxim 77:529edb329ee0 281 if (result == OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 282 {
IanBenzMaxim 77:529edb329ee0 283 result = OWSetSpeed(OneWireMaster::OverdriveSpeed);
IanBenzMaxim 77:529edb329ee0 284 }
IanBenzMaxim 77:529edb329ee0 285
IanBenzMaxim 77:529edb329ee0 286 return result;
IanBenzMaxim 77:529edb329ee0 287 }
IanBenzMaxim 77:529edb329ee0 288
IanBenzMaxim 77:529edb329ee0 289 OneWireMaster::CmdResult OneWireMaster::OWOverdriveMatchRom(const RomId & romId)
IanBenzMaxim 77:529edb329ee0 290 {
IanBenzMaxim 77:529edb329ee0 291 OneWireMaster::CmdResult result;
IanBenzMaxim 77:529edb329ee0 292
IanBenzMaxim 77:529edb329ee0 293 // use overdrive MatchROM
IanBenzMaxim 77:529edb329ee0 294 OWSetSpeed(OneWireMaster::StandardSpeed);
IanBenzMaxim 77:529edb329ee0 295
IanBenzMaxim 77:529edb329ee0 296 result = OWReset();
IanBenzMaxim 77:529edb329ee0 297 if (result == OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 298 {
IanBenzMaxim 77:529edb329ee0 299 result = OWWriteByte(OverdriveMatchRomCmd);
IanBenzMaxim 77:529edb329ee0 300 if (result == OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 301 {
IanBenzMaxim 77:529edb329ee0 302 OWSetSpeed(OneWireMaster::OverdriveSpeed);
IanBenzMaxim 77:529edb329ee0 303 // send ROM
IanBenzMaxim 77:529edb329ee0 304 result = OWWriteBlock(romId, RomId::byteLen);
IanBenzMaxim 77:529edb329ee0 305 }
IanBenzMaxim 77:529edb329ee0 306 }
IanBenzMaxim 77:529edb329ee0 307 return result;
IanBenzMaxim 77:529edb329ee0 308 }
IanBenzMaxim 77:529edb329ee0 309
IanBenzMaxim 77:529edb329ee0 310 OneWireMaster::CmdResult OneWireMaster::OWResume()
IanBenzMaxim 77:529edb329ee0 311 {
IanBenzMaxim 77:529edb329ee0 312 OneWireMaster::CmdResult result;
IanBenzMaxim 77:529edb329ee0 313
IanBenzMaxim 77:529edb329ee0 314 result = OWReset();
IanBenzMaxim 77:529edb329ee0 315 if (result == OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 316 {
IanBenzMaxim 77:529edb329ee0 317 result = OWWriteByte(ResumeCmd);
IanBenzMaxim 77:529edb329ee0 318 }
IanBenzMaxim 77:529edb329ee0 319
IanBenzMaxim 77:529edb329ee0 320 return result;
IanBenzMaxim 77:529edb329ee0 321 }
IanBenzMaxim 77:529edb329ee0 322
IanBenzMaxim 77:529edb329ee0 323 OneWireMaster::CmdResult OneWireMaster::OWSearch(SearchState & searchState)
IanBenzMaxim 77:529edb329ee0 324 {
IanBenzMaxim 77:529edb329ee0 325 uint8_t id_bit_number;
IanBenzMaxim 77:529edb329ee0 326 uint8_t last_zero, rom_byte_number;
IanBenzMaxim 77:529edb329ee0 327 uint8_t id_bit, cmp_id_bit;
IanBenzMaxim 77:529edb329ee0 328 uint8_t rom_byte_mask;
IanBenzMaxim 77:529edb329ee0 329 bool search_result;
IanBenzMaxim 77:529edb329ee0 330 uint8_t crc8 = 0;
IanBenzMaxim 77:529edb329ee0 331 OneWireMaster::SearchDirection search_direction;
IanBenzMaxim 77:529edb329ee0 332
IanBenzMaxim 77:529edb329ee0 333 // initialize for search
IanBenzMaxim 77:529edb329ee0 334 id_bit_number = 1;
IanBenzMaxim 77:529edb329ee0 335 last_zero = 0;
IanBenzMaxim 77:529edb329ee0 336 rom_byte_number = 0;
IanBenzMaxim 77:529edb329ee0 337 rom_byte_mask = 1;
IanBenzMaxim 77:529edb329ee0 338 search_result = false;
IanBenzMaxim 77:529edb329ee0 339
IanBenzMaxim 77:529edb329ee0 340 // if the last call was not the last one
IanBenzMaxim 77:529edb329ee0 341 if (!searchState.last_device_flag)
IanBenzMaxim 77:529edb329ee0 342 {
IanBenzMaxim 77:529edb329ee0 343 // 1-Wire reset
IanBenzMaxim 77:529edb329ee0 344 OneWireMaster::CmdResult result = OWReset();
IanBenzMaxim 77:529edb329ee0 345 if (result != OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 346 {
IanBenzMaxim 77:529edb329ee0 347 // reset the search
IanBenzMaxim 77:529edb329ee0 348 searchState.reset();
IanBenzMaxim 77:529edb329ee0 349 return result;
IanBenzMaxim 77:529edb329ee0 350 }
IanBenzMaxim 77:529edb329ee0 351
IanBenzMaxim 77:529edb329ee0 352 // issue the search command
IanBenzMaxim 77:529edb329ee0 353 OWWriteByte(SearchRomCmd);
IanBenzMaxim 77:529edb329ee0 354
IanBenzMaxim 77:529edb329ee0 355 // loop to do the search
IanBenzMaxim 77:529edb329ee0 356 do
IanBenzMaxim 77:529edb329ee0 357 {
IanBenzMaxim 77:529edb329ee0 358 // if this discrepancy if before the Last Discrepancy
IanBenzMaxim 77:529edb329ee0 359 // on a previous next then pick the same as last time
IanBenzMaxim 77:529edb329ee0 360 if (id_bit_number < searchState.last_discrepancy)
IanBenzMaxim 77:529edb329ee0 361 {
IanBenzMaxim 77:529edb329ee0 362 if ((searchState.romId[rom_byte_number] & rom_byte_mask) > 0)
IanBenzMaxim 77:529edb329ee0 363 {
IanBenzMaxim 77:529edb329ee0 364 search_direction = OneWireMaster::WriteOne;
IanBenzMaxim 77:529edb329ee0 365 }
IanBenzMaxim 77:529edb329ee0 366 else
IanBenzMaxim 77:529edb329ee0 367 {
IanBenzMaxim 77:529edb329ee0 368 search_direction = OneWireMaster::WriteZero;
IanBenzMaxim 77:529edb329ee0 369 }
IanBenzMaxim 77:529edb329ee0 370 }
IanBenzMaxim 77:529edb329ee0 371 else
IanBenzMaxim 77:529edb329ee0 372 {
IanBenzMaxim 77:529edb329ee0 373 // if equal to last pick 1, if not then pick 0
IanBenzMaxim 77:529edb329ee0 374 if (id_bit_number == searchState.last_discrepancy)
IanBenzMaxim 77:529edb329ee0 375 {
IanBenzMaxim 77:529edb329ee0 376 search_direction = OneWireMaster::WriteOne;
IanBenzMaxim 77:529edb329ee0 377 }
IanBenzMaxim 77:529edb329ee0 378 else
IanBenzMaxim 77:529edb329ee0 379 {
IanBenzMaxim 77:529edb329ee0 380 search_direction = OneWireMaster::WriteZero;
IanBenzMaxim 77:529edb329ee0 381 }
IanBenzMaxim 77:529edb329ee0 382 }
IanBenzMaxim 77:529edb329ee0 383
IanBenzMaxim 77:529edb329ee0 384 // Peform a triple operation on the DS2465 which will perform 2 read bits and 1 write bit
IanBenzMaxim 77:529edb329ee0 385 result = OWTriplet(search_direction, id_bit, cmp_id_bit);
IanBenzMaxim 77:529edb329ee0 386 if (result != OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 387 {
IanBenzMaxim 77:529edb329ee0 388 return result;
IanBenzMaxim 77:529edb329ee0 389 }
IanBenzMaxim 77:529edb329ee0 390
IanBenzMaxim 77:529edb329ee0 391 // check for no devices on 1-wire
IanBenzMaxim 77:529edb329ee0 392 if (id_bit && cmp_id_bit)
IanBenzMaxim 77:529edb329ee0 393 {
IanBenzMaxim 77:529edb329ee0 394 break;
IanBenzMaxim 77:529edb329ee0 395 }
IanBenzMaxim 77:529edb329ee0 396 else
IanBenzMaxim 77:529edb329ee0 397 {
IanBenzMaxim 77:529edb329ee0 398 if (!id_bit && !cmp_id_bit && (search_direction == OneWireMaster::WriteZero))
IanBenzMaxim 77:529edb329ee0 399 {
IanBenzMaxim 77:529edb329ee0 400 last_zero = id_bit_number;
IanBenzMaxim 77:529edb329ee0 401
IanBenzMaxim 77:529edb329ee0 402 // check for Last discrepancy in family
IanBenzMaxim 77:529edb329ee0 403 if (last_zero < 9)
IanBenzMaxim 77:529edb329ee0 404 {
IanBenzMaxim 77:529edb329ee0 405 searchState.last_family_discrepancy = last_zero;
IanBenzMaxim 77:529edb329ee0 406 }
IanBenzMaxim 77:529edb329ee0 407 }
IanBenzMaxim 77:529edb329ee0 408
IanBenzMaxim 77:529edb329ee0 409 // set or clear the bit in the ROM byte rom_byte_number
IanBenzMaxim 77:529edb329ee0 410 // with mask rom_byte_mask
IanBenzMaxim 77:529edb329ee0 411 if (search_direction == OneWireMaster::WriteOne)
IanBenzMaxim 77:529edb329ee0 412 {
IanBenzMaxim 77:529edb329ee0 413 searchState.romId[rom_byte_number] |= rom_byte_mask;
IanBenzMaxim 77:529edb329ee0 414 }
IanBenzMaxim 77:529edb329ee0 415 else
IanBenzMaxim 77:529edb329ee0 416 {
IanBenzMaxim 77:529edb329ee0 417 searchState.romId[rom_byte_number] &= (uint8_t)~rom_byte_mask;
IanBenzMaxim 77:529edb329ee0 418 }
IanBenzMaxim 77:529edb329ee0 419
IanBenzMaxim 77:529edb329ee0 420 // increment the byte counter id_bit_number
IanBenzMaxim 77:529edb329ee0 421 // and shift the mask rom_byte_mask
IanBenzMaxim 77:529edb329ee0 422 id_bit_number++;
IanBenzMaxim 77:529edb329ee0 423 rom_byte_mask <<= 1;
IanBenzMaxim 77:529edb329ee0 424
IanBenzMaxim 77:529edb329ee0 425 // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
IanBenzMaxim 77:529edb329ee0 426 if (rom_byte_mask == 0)
IanBenzMaxim 77:529edb329ee0 427 {
IanBenzMaxim 77:529edb329ee0 428 crc8 = RomId::calculateCrc8(crc8, searchState.romId[rom_byte_number]); // accumulate the CRC
IanBenzMaxim 77:529edb329ee0 429 rom_byte_number++;
IanBenzMaxim 77:529edb329ee0 430 rom_byte_mask = 1;
IanBenzMaxim 77:529edb329ee0 431 }
IanBenzMaxim 77:529edb329ee0 432 }
IanBenzMaxim 77:529edb329ee0 433 } while (rom_byte_number < RomId::byteLen); // loop until through all ROM bytes 0-7
IanBenzMaxim 77:529edb329ee0 434
IanBenzMaxim 77:529edb329ee0 435 // if the search was successful then
IanBenzMaxim 77:529edb329ee0 436 if (!((id_bit_number <= (RomId::byteLen * 8)) || (crc8 != 0)))
IanBenzMaxim 77:529edb329ee0 437 {
IanBenzMaxim 77:529edb329ee0 438 // search successful so set m_last_discrepancy,m_last_device_flag,search_result
IanBenzMaxim 77:529edb329ee0 439 searchState.last_discrepancy = last_zero;
IanBenzMaxim 77:529edb329ee0 440
IanBenzMaxim 77:529edb329ee0 441 // check for last device
IanBenzMaxim 77:529edb329ee0 442 if (searchState.last_discrepancy == 0)
IanBenzMaxim 77:529edb329ee0 443 {
IanBenzMaxim 77:529edb329ee0 444 searchState.last_device_flag = true;
IanBenzMaxim 77:529edb329ee0 445 }
IanBenzMaxim 77:529edb329ee0 446
IanBenzMaxim 77:529edb329ee0 447 search_result = true;
IanBenzMaxim 77:529edb329ee0 448 }
IanBenzMaxim 77:529edb329ee0 449 }
IanBenzMaxim 77:529edb329ee0 450
IanBenzMaxim 77:529edb329ee0 451 // if no device found then reset counters so next 'search' will be like a first
IanBenzMaxim 77:529edb329ee0 452 if (!search_result || (searchState.romId.familyCode() == 0))
IanBenzMaxim 77:529edb329ee0 453 {
IanBenzMaxim 77:529edb329ee0 454 searchState.reset();
IanBenzMaxim 77:529edb329ee0 455 search_result = false;
IanBenzMaxim 77:529edb329ee0 456 }
IanBenzMaxim 77:529edb329ee0 457
IanBenzMaxim 77:529edb329ee0 458 return (search_result ? OneWireMaster::Success : OneWireMaster::OperationFailure);
IanBenzMaxim 77:529edb329ee0 459 }