1-Wire® library for mbed. Complete 1-Wire library that supports our silicon masters along with a bit-bang master on the MAX32600MBED platform with one common interface for mbed. Slave support has also been included and more slaves will be added as time permits.

Dependents:   MAXREFDES131_Qt_Demo MAX32630FTHR_iButton_uSD_Logger MAX32630FTHR_DS18B20_uSD_Logger MAXREFDES130_131_Demo ... more

Superseded by MaximInterface.

Committer:
IanBenzMaxim
Date:
Mon May 09 15:04:23 2016 -0500
Revision:
71:562f5c702094
Parent:
57:1635f247ceae
Added default implementation of OWWriteBlock() and OWReadBlock() to OneWireMaster.

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