Implementation of 1-Wire with added Alarm Search Functionality

Dependents:   Max32630_One_Wire_Interface

Committer:
IanBenzMaxim
Date:
Fri May 13 07:48:35 2016 -0500
Revision:
74:23be10c32fa3
Parent:
73:2cecc1372acc
Child:
75:8b627804927c
Assimilated indentation and braces.

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 73:2cecc1372acc 36 using OneWire::Masters::OneWireMaster;
j3 15:f6cb0d906fb6 37
IanBenzMaxim 43:23017dcd2ec3 38 enum OW_ROM_CMD
IanBenzMaxim 43:23017dcd2ec3 39 {
IanBenzMaxim 43:23017dcd2ec3 40 READ_ROM = 0x33,
IanBenzMaxim 43:23017dcd2ec3 41 MATCH_ROM = 0x55,
IanBenzMaxim 43:23017dcd2ec3 42 SEARCH_ROM = 0xF0,
IanBenzMaxim 43:23017dcd2ec3 43 SKIP_ROM = 0xCC,
IanBenzMaxim 43:23017dcd2ec3 44 RESUME = 0xA5,
IanBenzMaxim 43:23017dcd2ec3 45 OVERDRIVE_SKIP_ROM = 0x3C,
IanBenzMaxim 43:23017dcd2ec3 46 OVERDRIVE_MATCH_ROM = 0x69
IanBenzMaxim 43:23017dcd2ec3 47 };
j3 15:f6cb0d906fb6 48
j3 15:f6cb0d906fb6 49
IanBenzMaxim 71:562f5c702094 50 //*********************************************************************
IanBenzMaxim 71:562f5c702094 51 OneWireMaster::CmdResult OneWireMaster::OWWriteBlock(const uint8_t *tran_buf, uint8_t tran_len)
IanBenzMaxim 71:562f5c702094 52 {
IanBenzMaxim 71:562f5c702094 53 CmdResult result;
IanBenzMaxim 74:23be10c32fa3 54
IanBenzMaxim 74:23be10c32fa3 55 for (uint8_t idx = 0; idx < tran_len; idx++)
IanBenzMaxim 71:562f5c702094 56 {
IanBenzMaxim 71:562f5c702094 57 result = OWWriteByte(tran_buf[idx]);
IanBenzMaxim 74:23be10c32fa3 58 if (result != Success)
IanBenzMaxim 71:562f5c702094 59 {
IanBenzMaxim 71:562f5c702094 60 break;
IanBenzMaxim 71:562f5c702094 61 }
IanBenzMaxim 71:562f5c702094 62 }
IanBenzMaxim 74:23be10c32fa3 63
IanBenzMaxim 71:562f5c702094 64 return result;
IanBenzMaxim 71:562f5c702094 65 }
IanBenzMaxim 71:562f5c702094 66
IanBenzMaxim 71:562f5c702094 67
IanBenzMaxim 71:562f5c702094 68 //*********************************************************************
IanBenzMaxim 71:562f5c702094 69 OneWireMaster::CmdResult OneWireMaster::OWReadBlock(uint8_t *rx_buf, uint8_t rx_len)
IanBenzMaxim 71:562f5c702094 70 {
IanBenzMaxim 71:562f5c702094 71 CmdResult result;
IanBenzMaxim 74:23be10c32fa3 72
IanBenzMaxim 74:23be10c32fa3 73 for (uint8_t idx = 0; idx < rx_len; idx++)
IanBenzMaxim 71:562f5c702094 74 {
IanBenzMaxim 71:562f5c702094 75 result = OWReadByte(rx_buf[idx]);
IanBenzMaxim 74:23be10c32fa3 76 if (result != Success)
IanBenzMaxim 71:562f5c702094 77 {
IanBenzMaxim 71:562f5c702094 78 break;
IanBenzMaxim 71:562f5c702094 79 }
IanBenzMaxim 71:562f5c702094 80 }
IanBenzMaxim 74:23be10c32fa3 81
IanBenzMaxim 71:562f5c702094 82 return result;
IanBenzMaxim 71:562f5c702094 83 }
IanBenzMaxim 71:562f5c702094 84
IanBenzMaxim 71:562f5c702094 85
IanBenzMaxim 32:bce180b544ed 86 OneWireMaster::CmdResult OneWireMaster::OWFirst(SearchState & searchState)
j3 15:f6cb0d906fb6 87 {
j3 17:b646b1e3970b 88 // reset the search state
IanBenzMaxim 32:bce180b544ed 89 searchState.reset();
j3 17:b646b1e3970b 90
IanBenzMaxim 74:23be10c32fa3 91 return OWSearch(searchState);
j3 15:f6cb0d906fb6 92 }
j3 15:f6cb0d906fb6 93
j3 15:f6cb0d906fb6 94
j3 15:f6cb0d906fb6 95 //*********************************************************************
IanBenzMaxim 32:bce180b544ed 96 OneWireMaster::CmdResult OneWireMaster::OWNext(SearchState & searchState)
j3 15:f6cb0d906fb6 97 {
j3 17:b646b1e3970b 98 // leave the search state alone
IanBenzMaxim 32:bce180b544ed 99 return OWSearch(searchState);
j3 15:f6cb0d906fb6 100 }
j3 15:f6cb0d906fb6 101
j3 15:f6cb0d906fb6 102
j3 15:f6cb0d906fb6 103 //*********************************************************************
j3 23:e8e403d61359 104 OneWireMaster::CmdResult OneWireMaster::OWVerify(const RomId & romId)
j3 15:f6cb0d906fb6 105 {
j3 23:e8e403d61359 106 OneWireMaster::CmdResult result;
IanBenzMaxim 32:bce180b544ed 107 SearchState searchState;
IanBenzMaxim 74:23be10c32fa3 108
j3 42:698635a0d073 109 searchState.romId = romId;
j3 15:f6cb0d906fb6 110
j3 15:f6cb0d906fb6 111 // set search to find the same device
IanBenzMaxim 32:bce180b544ed 112 searchState.last_discrepancy = 64;
IanBenzMaxim 32:bce180b544ed 113 searchState.last_device_flag = false;
j3 15:f6cb0d906fb6 114
IanBenzMaxim 32:bce180b544ed 115 result = OWSearch(searchState);
IanBenzMaxim 74:23be10c32fa3 116 if (result == OneWireMaster::Success)
j3 15:f6cb0d906fb6 117 {
j3 15:f6cb0d906fb6 118 // check if same device found
IanBenzMaxim 74:23be10c32fa3 119 if (romId != searchState.romId)
j3 15:f6cb0d906fb6 120 {
j3 23:e8e403d61359 121 result = OneWireMaster::OperationFailure;
j3 15:f6cb0d906fb6 122 }
j3 15:f6cb0d906fb6 123 }
j3 15:f6cb0d906fb6 124
j3 17:b646b1e3970b 125 return result;
j3 15:f6cb0d906fb6 126 }
j3 15:f6cb0d906fb6 127
j3 15:f6cb0d906fb6 128
j3 15:f6cb0d906fb6 129 //*********************************************************************
IanBenzMaxim 32:bce180b544ed 130 void OneWireMaster::OWTargetSetup(SearchState & searchState)
j3 15:f6cb0d906fb6 131 {
j3 15:f6cb0d906fb6 132 // set the search state to find SearchFamily type devices
IanBenzMaxim 73:2cecc1372acc 133 uint8_t familyCode = searchState.romId.familyCode();
IanBenzMaxim 32:bce180b544ed 134 searchState.reset();
IanBenzMaxim 32:bce180b544ed 135 searchState.romId.setFamilyCode(familyCode);
IanBenzMaxim 32:bce180b544ed 136 searchState.last_discrepancy = 64;
j3 15:f6cb0d906fb6 137 }
j3 5:ce108eeb878d 138
j3 5:ce108eeb878d 139
j3 5:ce108eeb878d 140 //*********************************************************************
IanBenzMaxim 32:bce180b544ed 141 void OneWireMaster::OWFamilySkipSetup(SearchState & searchState)
j3 15:f6cb0d906fb6 142 {
j3 15:f6cb0d906fb6 143 // set the Last discrepancy to last family discrepancy
IanBenzMaxim 32:bce180b544ed 144 searchState.last_discrepancy = searchState.last_family_discrepancy;
j3 17:b646b1e3970b 145
j3 15:f6cb0d906fb6 146 // clear the last family discrpepancy
IanBenzMaxim 32:bce180b544ed 147 searchState.last_family_discrepancy = 0;
j3 17:b646b1e3970b 148
j3 15:f6cb0d906fb6 149 // check for end of list
IanBenzMaxim 32:bce180b544ed 150 if (searchState.last_discrepancy == 0)
j3 15:f6cb0d906fb6 151 {
IanBenzMaxim 32:bce180b544ed 152 searchState.last_device_flag = true;
j3 15:f6cb0d906fb6 153 }
j3 15:f6cb0d906fb6 154 }
j3 15:f6cb0d906fb6 155
j3 15:f6cb0d906fb6 156
j3 15:f6cb0d906fb6 157 //*********************************************************************
j3 23:e8e403d61359 158 OneWireMaster::CmdResult OneWireMaster::OWReadROM(RomId & romId)
j3 15:f6cb0d906fb6 159 {
j3 23:e8e403d61359 160 OneWireMaster::CmdResult result;
j3 17:b646b1e3970b 161 uint8_t buf[2 + RomId::byteLen];
j3 17:b646b1e3970b 162
j3 17:b646b1e3970b 163 result = OWReset();
j3 23:e8e403d61359 164 if (result == OneWireMaster::Success)
j3 15:f6cb0d906fb6 165 {
IanBenzMaxim 24:8942d8478d68 166 result = OWWriteByte(READ_ROM);
j3 17:b646b1e3970b 167 }
j3 17:b646b1e3970b 168
j3 17:b646b1e3970b 169 // read the ROM
j3 23:e8e403d61359 170 if (result == OneWireMaster::Success)
j3 17:b646b1e3970b 171 {
j3 17:b646b1e3970b 172 result = OWReadBlock(buf, RomId::byteLen);
j3 15:f6cb0d906fb6 173 }
IanBenzMaxim 74:23be10c32fa3 174
j3 17:b646b1e3970b 175 // verify CRC8
IanBenzMaxim 24:8942d8478d68 176 if ((result == OneWireMaster::Success) && (RomId::calculateCRC8(buf, RomId::byteLen) == 0))
j3 17:b646b1e3970b 177 {
IanBenzMaxim 74:23be10c32fa3 178 romId = RomId(reinterpret_cast<uint8_t(&)[RomId::byteLen]>(buf[0]));
j3 17:b646b1e3970b 179 }
j3 17:b646b1e3970b 180
j3 17:b646b1e3970b 181 return result;
j3 15:f6cb0d906fb6 182 }
IanBenzMaxim 74:23be10c32fa3 183
j3 15:f6cb0d906fb6 184
j3 15:f6cb0d906fb6 185 //*********************************************************************
j3 23:e8e403d61359 186 OneWireMaster::CmdResult OneWireMaster::OWSkipROM(void)
j3 15:f6cb0d906fb6 187 {
j3 23:e8e403d61359 188 OneWireMaster::CmdResult result;
IanBenzMaxim 74:23be10c32fa3 189
j3 17:b646b1e3970b 190 result = OWReset();
IanBenzMaxim 74:23be10c32fa3 191 if (result == OneWireMaster::Success)
j3 15:f6cb0d906fb6 192 {
IanBenzMaxim 24:8942d8478d68 193 result = OWWriteByte(SKIP_ROM);
j3 15:f6cb0d906fb6 194 }
IanBenzMaxim 74:23be10c32fa3 195
j3 17:b646b1e3970b 196 return result;
j3 15:f6cb0d906fb6 197 }
IanBenzMaxim 74:23be10c32fa3 198
j3 15:f6cb0d906fb6 199
j3 15:f6cb0d906fb6 200 //*********************************************************************
j3 23:e8e403d61359 201 OneWireMaster::CmdResult OneWireMaster::OWMatchROM(const RomId & romId)
j3 15:f6cb0d906fb6 202 {
j3 23:e8e403d61359 203 OneWireMaster::CmdResult result;
IanBenzMaxim 74:23be10c32fa3 204
j3 17:b646b1e3970b 205 uint8_t buf[1 + RomId::byteLen];
j3 17:b646b1e3970b 206
j3 17:b646b1e3970b 207 // use MatchROM
j3 17:b646b1e3970b 208 result = OWReset();
IanBenzMaxim 74:23be10c32fa3 209 if (result == OneWireMaster::Success)
j3 15:f6cb0d906fb6 210 {
IanBenzMaxim 24:8942d8478d68 211 buf[0] = MATCH_ROM;
j3 17:b646b1e3970b 212 std::memcpy(&buf[1], romId, RomId::byteLen);
j3 17:b646b1e3970b 213 // send command and rom
j3 17:b646b1e3970b 214 result = OWWriteBlock(buf, 1 + RomId::byteLen);
j3 15:f6cb0d906fb6 215 }
j3 17:b646b1e3970b 216
j3 17:b646b1e3970b 217 return result;
j3 15:f6cb0d906fb6 218 }
IanBenzMaxim 74:23be10c32fa3 219
j3 15:f6cb0d906fb6 220
j3 15:f6cb0d906fb6 221 //*********************************************************************
j3 23:e8e403d61359 222 OneWireMaster::CmdResult OneWireMaster::OWOverdriveSkipROM(void)
j3 15:f6cb0d906fb6 223 {
IanBenzMaxim 32:bce180b544ed 224 OneWireMaster::CmdResult result = OWSetSpeed(SPEED_STANDARD);
IanBenzMaxim 74:23be10c32fa3 225
j3 23:e8e403d61359 226 if (result == OneWireMaster::Success)
j3 15:f6cb0d906fb6 227 {
j3 17:b646b1e3970b 228 result = OWReset();
j3 15:f6cb0d906fb6 229 }
IanBenzMaxim 74:23be10c32fa3 230
j3 23:e8e403d61359 231 if (result == OneWireMaster::Success)
j3 17:b646b1e3970b 232 {
IanBenzMaxim 24:8942d8478d68 233 result = OWWriteByte(OVERDRIVE_SKIP_ROM);
j3 17:b646b1e3970b 234 }
IanBenzMaxim 74:23be10c32fa3 235
j3 23:e8e403d61359 236 if (result == OneWireMaster::Success)
j3 17:b646b1e3970b 237 {
IanBenzMaxim 32:bce180b544ed 238 result = OWSetSpeed(SPEED_OVERDRIVE);
j3 17:b646b1e3970b 239 }
IanBenzMaxim 74:23be10c32fa3 240
j3 17:b646b1e3970b 241 return result;
j3 15:f6cb0d906fb6 242 }
IanBenzMaxim 74:23be10c32fa3 243
j3 15:f6cb0d906fb6 244
j3 15:f6cb0d906fb6 245 //*********************************************************************
j3 23:e8e403d61359 246 OneWireMaster::CmdResult OneWireMaster::OWOverdriveMatchROM(const RomId & romId)
j3 15:f6cb0d906fb6 247 {
j3 23:e8e403d61359 248 OneWireMaster::CmdResult result;
IanBenzMaxim 74:23be10c32fa3 249
j3 17:b646b1e3970b 250 // use overdrive MatchROM
IanBenzMaxim 32:bce180b544ed 251 OWSetSpeed(SPEED_STANDARD);
IanBenzMaxim 74:23be10c32fa3 252
j3 17:b646b1e3970b 253 result = OWReset();
IanBenzMaxim 74:23be10c32fa3 254 if (result == OneWireMaster::Success)
j3 15:f6cb0d906fb6 255 {
IanBenzMaxim 24:8942d8478d68 256 result = OWWriteByte(OVERDRIVE_MATCH_ROM);
IanBenzMaxim 74:23be10c32fa3 257 if (result == OneWireMaster::Success)
j3 15:f6cb0d906fb6 258 {
IanBenzMaxim 32:bce180b544ed 259 OWSetSpeed(SPEED_OVERDRIVE);
j3 17:b646b1e3970b 260 // send ROM
j3 17:b646b1e3970b 261 result = OWWriteBlock(romId, RomId::byteLen);
j3 15:f6cb0d906fb6 262 }
j3 15:f6cb0d906fb6 263 }
j3 17:b646b1e3970b 264 return result;
j3 15:f6cb0d906fb6 265 }
IanBenzMaxim 74:23be10c32fa3 266
j3 15:f6cb0d906fb6 267
j3 15:f6cb0d906fb6 268 //*********************************************************************
j3 23:e8e403d61359 269 OneWireMaster::CmdResult OneWireMaster::OWResume(void)
j3 15:f6cb0d906fb6 270 {
j3 23:e8e403d61359 271 OneWireMaster::CmdResult result;
IanBenzMaxim 74:23be10c32fa3 272
j3 17:b646b1e3970b 273 result = OWReset();
IanBenzMaxim 74:23be10c32fa3 274 if (result == OneWireMaster::Success)
j3 15:f6cb0d906fb6 275 {
IanBenzMaxim 24:8942d8478d68 276 result = OWWriteByte(RESUME);
j3 15:f6cb0d906fb6 277 }
IanBenzMaxim 74:23be10c32fa3 278
j3 17:b646b1e3970b 279 return result;
j3 15:f6cb0d906fb6 280 }
j3 15:f6cb0d906fb6 281
j3 15:f6cb0d906fb6 282
IanBenzMaxim 32:bce180b544ed 283 OneWireMaster::CmdResult OneWireMaster::OWSearch(SearchState & searchState)
IanBenzMaxim 32:bce180b544ed 284 {
IanBenzMaxim 74:23be10c32fa3 285 uint8_t id_bit_number;
IanBenzMaxim 74:23be10c32fa3 286 uint8_t last_zero, rom_byte_number;
IanBenzMaxim 74:23be10c32fa3 287 uint8_t id_bit, cmp_id_bit;
IanBenzMaxim 74:23be10c32fa3 288 uint8_t rom_byte_mask;
IanBenzMaxim 74:23be10c32fa3 289 bool search_result;
IanBenzMaxim 74:23be10c32fa3 290 uint8_t crc8 = 0;
IanBenzMaxim 74:23be10c32fa3 291 SearchDirection search_direction;
IanBenzMaxim 32:bce180b544ed 292
IanBenzMaxim 74:23be10c32fa3 293 // initialize for search
IanBenzMaxim 74:23be10c32fa3 294 id_bit_number = 1;
IanBenzMaxim 74:23be10c32fa3 295 last_zero = 0;
IanBenzMaxim 74:23be10c32fa3 296 rom_byte_number = 0;
IanBenzMaxim 74:23be10c32fa3 297 rom_byte_mask = 1;
IanBenzMaxim 74:23be10c32fa3 298 search_result = false;
IanBenzMaxim 32:bce180b544ed 299
IanBenzMaxim 74:23be10c32fa3 300 // if the last call was not the last one
IanBenzMaxim 74:23be10c32fa3 301 if (!searchState.last_device_flag)
IanBenzMaxim 74:23be10c32fa3 302 {
IanBenzMaxim 74:23be10c32fa3 303 // 1-Wire reset
IanBenzMaxim 74:23be10c32fa3 304 OneWireMaster::CmdResult result = OWReset();
IanBenzMaxim 74:23be10c32fa3 305 if (result != OneWireMaster::Success)
IanBenzMaxim 74:23be10c32fa3 306 {
IanBenzMaxim 74:23be10c32fa3 307 // reset the search
IanBenzMaxim 74:23be10c32fa3 308 searchState.reset();
IanBenzMaxim 74:23be10c32fa3 309 return result;
IanBenzMaxim 74:23be10c32fa3 310 }
IanBenzMaxim 32:bce180b544ed 311
IanBenzMaxim 74:23be10c32fa3 312 // issue the search command
IanBenzMaxim 74:23be10c32fa3 313 OneWireMaster::OWWriteByte(SEARCH_ROM);
IanBenzMaxim 32:bce180b544ed 314
IanBenzMaxim 74:23be10c32fa3 315 // loop to do the search
IanBenzMaxim 74:23be10c32fa3 316 do
IanBenzMaxim 74:23be10c32fa3 317 {
IanBenzMaxim 74:23be10c32fa3 318 // if this discrepancy if before the Last Discrepancy
IanBenzMaxim 74:23be10c32fa3 319 // on a previous next then pick the same as last time
IanBenzMaxim 74:23be10c32fa3 320 if (id_bit_number < searchState.last_discrepancy)
IanBenzMaxim 74:23be10c32fa3 321 {
IanBenzMaxim 74:23be10c32fa3 322 if ((searchState.romId[rom_byte_number] & rom_byte_mask) > 0)
IanBenzMaxim 74:23be10c32fa3 323 {
IanBenzMaxim 74:23be10c32fa3 324 search_direction = DIRECTION_WRITE_ONE;
IanBenzMaxim 74:23be10c32fa3 325 }
IanBenzMaxim 74:23be10c32fa3 326 else
IanBenzMaxim 74:23be10c32fa3 327 {
IanBenzMaxim 74:23be10c32fa3 328 search_direction = DIRECTION_WRITE_ZERO;
IanBenzMaxim 74:23be10c32fa3 329 }
IanBenzMaxim 74:23be10c32fa3 330 }
IanBenzMaxim 32:bce180b544ed 331 else
IanBenzMaxim 74:23be10c32fa3 332 {
IanBenzMaxim 74:23be10c32fa3 333 // if equal to last pick 1, if not then pick 0
IanBenzMaxim 74:23be10c32fa3 334 if (id_bit_number == searchState.last_discrepancy)
IanBenzMaxim 74:23be10c32fa3 335 {
IanBenzMaxim 74:23be10c32fa3 336 search_direction = DIRECTION_WRITE_ONE;
IanBenzMaxim 74:23be10c32fa3 337 }
IanBenzMaxim 74:23be10c32fa3 338 else
IanBenzMaxim 74:23be10c32fa3 339 {
IanBenzMaxim 74:23be10c32fa3 340 search_direction = DIRECTION_WRITE_ZERO;
IanBenzMaxim 74:23be10c32fa3 341 }
IanBenzMaxim 74:23be10c32fa3 342 }
IanBenzMaxim 32:bce180b544ed 343
IanBenzMaxim 74:23be10c32fa3 344 // Peform a triple operation on the DS2465 which will perform 2 read bits and 1 write bit
IanBenzMaxim 74:23be10c32fa3 345 result = OWTriplet(search_direction, id_bit, cmp_id_bit);
IanBenzMaxim 74:23be10c32fa3 346 if (result != OneWireMaster::Success)
IanBenzMaxim 32:bce180b544ed 347 {
IanBenzMaxim 74:23be10c32fa3 348 return result;
IanBenzMaxim 32:bce180b544ed 349 }
IanBenzMaxim 32:bce180b544ed 350
IanBenzMaxim 74:23be10c32fa3 351 // check for no devices on 1-wire
IanBenzMaxim 74:23be10c32fa3 352 if ((id_bit) && (cmp_id_bit))
IanBenzMaxim 74:23be10c32fa3 353 {
IanBenzMaxim 74:23be10c32fa3 354 break;
IanBenzMaxim 74:23be10c32fa3 355 }
IanBenzMaxim 32:bce180b544ed 356 else
IanBenzMaxim 74:23be10c32fa3 357 {
IanBenzMaxim 74:23be10c32fa3 358 if ((!id_bit) && (!cmp_id_bit) && (search_direction == DIRECTION_WRITE_ZERO))
IanBenzMaxim 74:23be10c32fa3 359 {
IanBenzMaxim 74:23be10c32fa3 360 last_zero = id_bit_number;
IanBenzMaxim 32:bce180b544ed 361
IanBenzMaxim 74:23be10c32fa3 362 // check for Last discrepancy in family
IanBenzMaxim 74:23be10c32fa3 363 if (last_zero < 9)
IanBenzMaxim 74:23be10c32fa3 364 {
IanBenzMaxim 74:23be10c32fa3 365 searchState.last_family_discrepancy = last_zero;
IanBenzMaxim 74:23be10c32fa3 366 }
IanBenzMaxim 74:23be10c32fa3 367 }
IanBenzMaxim 32:bce180b544ed 368
IanBenzMaxim 74:23be10c32fa3 369 // set or clear the bit in the ROM byte rom_byte_number
IanBenzMaxim 74:23be10c32fa3 370 // with mask rom_byte_mask
IanBenzMaxim 74:23be10c32fa3 371 if (search_direction == DIRECTION_WRITE_ONE)
IanBenzMaxim 74:23be10c32fa3 372 {
IanBenzMaxim 74:23be10c32fa3 373 searchState.romId[rom_byte_number] |= rom_byte_mask;
IanBenzMaxim 74:23be10c32fa3 374 }
IanBenzMaxim 74:23be10c32fa3 375 else
IanBenzMaxim 74:23be10c32fa3 376 {
IanBenzMaxim 74:23be10c32fa3 377 searchState.romId[rom_byte_number] &= (uint8_t)~rom_byte_mask;
IanBenzMaxim 74:23be10c32fa3 378 }
IanBenzMaxim 74:23be10c32fa3 379
IanBenzMaxim 74:23be10c32fa3 380 // increment the byte counter id_bit_number
IanBenzMaxim 74:23be10c32fa3 381 // and shift the mask rom_byte_mask
IanBenzMaxim 74:23be10c32fa3 382 id_bit_number++;
IanBenzMaxim 74:23be10c32fa3 383 rom_byte_mask <<= 1;
IanBenzMaxim 32:bce180b544ed 384
IanBenzMaxim 74:23be10c32fa3 385 // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
IanBenzMaxim 74:23be10c32fa3 386 if (rom_byte_mask == 0)
IanBenzMaxim 74:23be10c32fa3 387 {
IanBenzMaxim 74:23be10c32fa3 388 crc8 = RomId::calculateCRC8(crc8, searchState.romId[rom_byte_number]); // accumulate the CRC
IanBenzMaxim 74:23be10c32fa3 389 rom_byte_number++;
IanBenzMaxim 74:23be10c32fa3 390 rom_byte_mask = 1;
IanBenzMaxim 74:23be10c32fa3 391 }
IanBenzMaxim 74:23be10c32fa3 392 }
IanBenzMaxim 74:23be10c32fa3 393 } while (rom_byte_number < RomId::byteLen); // loop until through all ROM bytes 0-7
IanBenzMaxim 32:bce180b544ed 394
IanBenzMaxim 74:23be10c32fa3 395 // if the search was successful then
IanBenzMaxim 74:23be10c32fa3 396 if (!((id_bit_number <= (RomId::byteLen * 8)) || (crc8 != 0)))
IanBenzMaxim 74:23be10c32fa3 397 {
IanBenzMaxim 74:23be10c32fa3 398 // search successful so set m_last_discrepancy,m_last_device_flag,search_result
IanBenzMaxim 74:23be10c32fa3 399 searchState.last_discrepancy = last_zero;
IanBenzMaxim 32:bce180b544ed 400
IanBenzMaxim 74:23be10c32fa3 401 // check for last device
IanBenzMaxim 74:23be10c32fa3 402 if (searchState.last_discrepancy == 0)
IanBenzMaxim 74:23be10c32fa3 403 {
IanBenzMaxim 74:23be10c32fa3 404 searchState.last_device_flag = true;
IanBenzMaxim 74:23be10c32fa3 405 }
IanBenzMaxim 32:bce180b544ed 406
IanBenzMaxim 74:23be10c32fa3 407 search_result = true;
IanBenzMaxim 74:23be10c32fa3 408 }
IanBenzMaxim 74:23be10c32fa3 409 }
IanBenzMaxim 32:bce180b544ed 410
IanBenzMaxim 74:23be10c32fa3 411 // if no device found then reset counters so next 'search' will be like a first
IanBenzMaxim 74:23be10c32fa3 412 if (!search_result || (searchState.romId.familyCode() == 0))
IanBenzMaxim 74:23be10c32fa3 413 {
IanBenzMaxim 74:23be10c32fa3 414 searchState.reset();
IanBenzMaxim 74:23be10c32fa3 415 search_result = false;
IanBenzMaxim 74:23be10c32fa3 416 }
IanBenzMaxim 74:23be10c32fa3 417
IanBenzMaxim 74:23be10c32fa3 418 return (search_result ? OneWireMaster::Success : OneWireMaster::OperationFailure);
IanBenzMaxim 32:bce180b544ed 419 }
IanBenzMaxim 32:bce180b544ed 420
IanBenzMaxim 32:bce180b544ed 421
IanBenzMaxim 73:2cecc1372acc 422 OneWireMaster::CmdResult OneWireMaster::OWTriplet(SearchDirection & search_direction, uint8_t & sbr, uint8_t & tsb)
IanBenzMaxim 32:bce180b544ed 423 {
IanBenzMaxim 32:bce180b544ed 424 CmdResult result;
IanBenzMaxim 32:bce180b544ed 425 result = OWReadBit(sbr);
IanBenzMaxim 32:bce180b544ed 426 if (result == Success)
IanBenzMaxim 74:23be10c32fa3 427 {
IanBenzMaxim 32:bce180b544ed 428 result = OWReadBit(tsb);
IanBenzMaxim 74:23be10c32fa3 429 }
IanBenzMaxim 32:bce180b544ed 430 if (result == Success)
IanBenzMaxim 32:bce180b544ed 431 {
IanBenzMaxim 57:1635f247ceae 432 if (sbr)
IanBenzMaxim 74:23be10c32fa3 433 {
IanBenzMaxim 32:bce180b544ed 434 search_direction = DIRECTION_WRITE_ONE;
IanBenzMaxim 74:23be10c32fa3 435 }
IanBenzMaxim 57:1635f247ceae 436 else if (tsb)
IanBenzMaxim 74:23be10c32fa3 437 {
IanBenzMaxim 32:bce180b544ed 438 search_direction = DIRECTION_WRITE_ZERO;
IanBenzMaxim 74:23be10c32fa3 439 }
IanBenzMaxim 32:bce180b544ed 440 // else: use search_direction parameter
IanBenzMaxim 74:23be10c32fa3 441
IanBenzMaxim 32:bce180b544ed 442 result = OWWriteBit((search_direction == DIRECTION_WRITE_ONE) ? 1 : 0);
IanBenzMaxim 32:bce180b544ed 443 }
IanBenzMaxim 32:bce180b544ed 444 return result;
IanBenzMaxim 32:bce180b544ed 445 }
IanBenzMaxim 32:bce180b544ed 446
IanBenzMaxim 32:bce180b544ed 447
j3 17:b646b1e3970b 448 uint16_t OneWireMaster::calculateCRC16(uint16_t CRC16, uint16_t data)
j3 15:f6cb0d906fb6 449 {
IanBenzMaxim 74:23be10c32fa3 450 const uint16_t _oddparity[] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
IanBenzMaxim 74:23be10c32fa3 451
IanBenzMaxim 74:23be10c32fa3 452 data = (data ^ (CRC16 & 0xff)) & 0xff;
IanBenzMaxim 74:23be10c32fa3 453 CRC16 >>= 8;
j3 17:b646b1e3970b 454
IanBenzMaxim 74:23be10c32fa3 455 if (_oddparity[data & 0xf] ^ _oddparity[data >> 4])
IanBenzMaxim 74:23be10c32fa3 456 {
IanBenzMaxim 74:23be10c32fa3 457 CRC16 ^= 0xc001;
IanBenzMaxim 74:23be10c32fa3 458 }
j3 17:b646b1e3970b 459
IanBenzMaxim 74:23be10c32fa3 460 data <<= 6;
IanBenzMaxim 74:23be10c32fa3 461 CRC16 ^= data;
IanBenzMaxim 74:23be10c32fa3 462 data <<= 1;
IanBenzMaxim 74:23be10c32fa3 463 CRC16 ^= data;
j3 17:b646b1e3970b 464
IanBenzMaxim 74:23be10c32fa3 465 return CRC16;
j3 15:f6cb0d906fb6 466 }
j3 15:f6cb0d906fb6 467
IanBenzMaxim 48:6f9208ae280e 468
j3 17:b646b1e3970b 469 uint16_t OneWireMaster::calculateCRC16(const uint8_t * data, size_t data_offset, size_t data_len, uint16_t crc)
IanBenzMaxim 74:23be10c32fa3 470 {
IanBenzMaxim 74:23be10c32fa3 471 for (size_t i = data_offset; i < (data_len + data_offset); i++)
IanBenzMaxim 74:23be10c32fa3 472 {
IanBenzMaxim 74:23be10c32fa3 473 crc = calculateCRC16(crc, data[i]);
IanBenzMaxim 74:23be10c32fa3 474 }
IanBenzMaxim 74:23be10c32fa3 475 return crc;
IanBenzMaxim 48:6f9208ae280e 476 }