Implementation of 1-Wire with added Alarm Search Functionality

Dependents:   Max32630_One_Wire_Interface

Committer:
IanBenzMaxim
Date:
Fri Mar 25 11:11:59 2016 -0500
Revision:
27:d5aaefa252f1
Parent:
26:a361e3f42ba5
Child:
32:bce180b544ed
Do not reconfigure DS2465 if requested speed or level is already set. Use forward declarations to speed up compilation.

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
j3 17:b646b1e3970b 41 const uint16_t OneWireMaster::_oddparity[] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
j3 15:f6cb0d906fb6 42
j3 15:f6cb0d906fb6 43
j3 23:e8e403d61359 44 OneWireMaster::CmdResult OneWireMaster::OWFirst(RomId & romId)
j3 15:f6cb0d906fb6 45 {
j3 17:b646b1e3970b 46 // reset the search state
j3 17:b646b1e3970b 47 _last_discrepancy = 0;
j3 17:b646b1e3970b 48 _last_device_flag = 0;
j3 17:b646b1e3970b 49 _last_family_discrepancy = 0;
j3 17:b646b1e3970b 50
j3 17:b646b1e3970b 51 return OWSearch(romId);
j3 15:f6cb0d906fb6 52 }
j3 15:f6cb0d906fb6 53
j3 15:f6cb0d906fb6 54
j3 15:f6cb0d906fb6 55 //*********************************************************************
j3 23:e8e403d61359 56 OneWireMaster::CmdResult OneWireMaster::OWNext(RomId & romId)
j3 15:f6cb0d906fb6 57 {
j3 17:b646b1e3970b 58 // leave the search state alone
j3 17:b646b1e3970b 59 return OWSearch(romId);
j3 15:f6cb0d906fb6 60 }
j3 15:f6cb0d906fb6 61
j3 15:f6cb0d906fb6 62
j3 15:f6cb0d906fb6 63 //*********************************************************************
j3 23:e8e403d61359 64 OneWireMaster::CmdResult OneWireMaster::OWVerify(const RomId & romId)
j3 15:f6cb0d906fb6 65 {
j3 23:e8e403d61359 66 OneWireMaster::CmdResult result;
j3 17:b646b1e3970b 67 RomId romIdCopy(romId);
j3 17:b646b1e3970b 68 int ld_backup, ldf_backup, lfd_backup;
j3 15:f6cb0d906fb6 69
j3 15:f6cb0d906fb6 70 // keep a backup copy of the current state
j3 15:f6cb0d906fb6 71 ld_backup = _last_discrepancy;
j3 15:f6cb0d906fb6 72 ldf_backup = _last_device_flag;
j3 15:f6cb0d906fb6 73 lfd_backup = _last_family_discrepancy;
j3 15:f6cb0d906fb6 74
j3 15:f6cb0d906fb6 75 // set search to find the same device
j3 15:f6cb0d906fb6 76 _last_discrepancy = 64;
IanBenzMaxim 21:00c94aeb533e 77 _last_device_flag = false;
j3 15:f6cb0d906fb6 78
j3 17:b646b1e3970b 79 result = OWSearch(romIdCopy);
j3 23:e8e403d61359 80 if (result == OneWireMaster::Success)
j3 15:f6cb0d906fb6 81 {
j3 15:f6cb0d906fb6 82 // check if same device found
j3 17:b646b1e3970b 83 if (romId != romIdCopy)
j3 15:f6cb0d906fb6 84 {
j3 23:e8e403d61359 85 result = OneWireMaster::OperationFailure;
j3 15:f6cb0d906fb6 86 }
j3 15:f6cb0d906fb6 87 }
j3 15:f6cb0d906fb6 88
j3 15:f6cb0d906fb6 89 // restore the search state
j3 15:f6cb0d906fb6 90 _last_discrepancy = ld_backup;
j3 15:f6cb0d906fb6 91 _last_device_flag = ldf_backup;
j3 15:f6cb0d906fb6 92 _last_family_discrepancy = lfd_backup;
j3 17:b646b1e3970b 93
j3 15:f6cb0d906fb6 94 // return the result of the verify
j3 17:b646b1e3970b 95 return result;
j3 15:f6cb0d906fb6 96 }
j3 15:f6cb0d906fb6 97
j3 15:f6cb0d906fb6 98
j3 15:f6cb0d906fb6 99 //*********************************************************************
j3 17:b646b1e3970b 100 void OneWireMaster::OWTargetSetup(RomId & romId)
j3 15:f6cb0d906fb6 101 {
j3 15:f6cb0d906fb6 102 // set the search state to find SearchFamily type devices
j3 17:b646b1e3970b 103 for (int i = 1; i < 8; i++)
j3 15:f6cb0d906fb6 104 {
j3 17:b646b1e3970b 105 romId[i] = 0;
j3 15:f6cb0d906fb6 106 }
j3 15:f6cb0d906fb6 107
j3 15:f6cb0d906fb6 108 _last_discrepancy = 64;
j3 15:f6cb0d906fb6 109 _last_family_discrepancy = 0;
j3 15:f6cb0d906fb6 110 _last_device_flag = false;
j3 15:f6cb0d906fb6 111 }
j3 5:ce108eeb878d 112
j3 5:ce108eeb878d 113
j3 5:ce108eeb878d 114 //*********************************************************************
j3 15:f6cb0d906fb6 115 void OneWireMaster::OWFamilySkipSetup(void)
j3 15:f6cb0d906fb6 116 {
j3 15:f6cb0d906fb6 117 // set the Last discrepancy to last family discrepancy
j3 15:f6cb0d906fb6 118 _last_discrepancy = _last_family_discrepancy;
j3 17:b646b1e3970b 119
j3 15:f6cb0d906fb6 120 // clear the last family discrpepancy
j3 15:f6cb0d906fb6 121 _last_family_discrepancy = 0;
j3 17:b646b1e3970b 122
j3 15:f6cb0d906fb6 123 // check for end of list
j3 17:b646b1e3970b 124 if (_last_discrepancy == 0)
j3 15:f6cb0d906fb6 125 {
j3 15:f6cb0d906fb6 126 _last_device_flag = true;
j3 15:f6cb0d906fb6 127 }
j3 15:f6cb0d906fb6 128 }
j3 15:f6cb0d906fb6 129
j3 15:f6cb0d906fb6 130
j3 15:f6cb0d906fb6 131 //*********************************************************************
j3 23:e8e403d61359 132 OneWireMaster::CmdResult OneWireMaster::OWReadROM(RomId & romId)
j3 15:f6cb0d906fb6 133 {
j3 23:e8e403d61359 134 OneWireMaster::CmdResult result;
j3 17:b646b1e3970b 135 uint8_t buf[2 + RomId::byteLen];
j3 17:b646b1e3970b 136
j3 17:b646b1e3970b 137 result = OWReset();
j3 23:e8e403d61359 138 if (result == OneWireMaster::Success)
j3 15:f6cb0d906fb6 139 {
IanBenzMaxim 24:8942d8478d68 140 result = OWWriteByte(READ_ROM);
j3 17:b646b1e3970b 141 }
j3 17:b646b1e3970b 142
j3 17:b646b1e3970b 143 // read the ROM
j3 23:e8e403d61359 144 if (result == OneWireMaster::Success)
j3 17:b646b1e3970b 145 {
j3 17:b646b1e3970b 146 result = OWReadBlock(buf, RomId::byteLen);
j3 15:f6cb0d906fb6 147 }
j3 15:f6cb0d906fb6 148
j3 17:b646b1e3970b 149 // verify CRC8
IanBenzMaxim 24:8942d8478d68 150 if ((result == OneWireMaster::Success) && (RomId::calculateCRC8(buf, RomId::byteLen) == 0))
j3 17:b646b1e3970b 151 {
j3 17:b646b1e3970b 152 romId = RomId(reinterpret_cast<std::uint8_t (&)[RomId::byteLen]>(buf[0]));
j3 17:b646b1e3970b 153 }
j3 17:b646b1e3970b 154
j3 17:b646b1e3970b 155 return result;
j3 15:f6cb0d906fb6 156 }
j3 15:f6cb0d906fb6 157
j3 15:f6cb0d906fb6 158
j3 15:f6cb0d906fb6 159 //*********************************************************************
j3 23:e8e403d61359 160 OneWireMaster::CmdResult OneWireMaster::OWSkipROM(void)
j3 15:f6cb0d906fb6 161 {
j3 23:e8e403d61359 162 OneWireMaster::CmdResult result;
j3 15:f6cb0d906fb6 163
j3 17:b646b1e3970b 164 result = OWReset();
j3 23:e8e403d61359 165 if (result == OneWireMaster::Success)
j3 15:f6cb0d906fb6 166 {
IanBenzMaxim 24:8942d8478d68 167 result = OWWriteByte(SKIP_ROM);
j3 15:f6cb0d906fb6 168 }
j3 15:f6cb0d906fb6 169
j3 17:b646b1e3970b 170 return result;
j3 15:f6cb0d906fb6 171 }
j3 15:f6cb0d906fb6 172
j3 15:f6cb0d906fb6 173
j3 15:f6cb0d906fb6 174 //*********************************************************************
j3 23:e8e403d61359 175 OneWireMaster::CmdResult OneWireMaster::OWMatchROM(const RomId & romId)
j3 15:f6cb0d906fb6 176 {
j3 23:e8e403d61359 177 OneWireMaster::CmdResult result;
j3 15:f6cb0d906fb6 178
j3 17:b646b1e3970b 179 uint8_t buf[1 + RomId::byteLen];
j3 17:b646b1e3970b 180
j3 17:b646b1e3970b 181 // use MatchROM
j3 17:b646b1e3970b 182 result = OWReset();
j3 23:e8e403d61359 183 if (result == OneWireMaster::Success)
j3 15:f6cb0d906fb6 184 {
IanBenzMaxim 24:8942d8478d68 185 buf[0] = MATCH_ROM;
j3 17:b646b1e3970b 186 std::memcpy(&buf[1], romId, RomId::byteLen);
j3 17:b646b1e3970b 187 // send command and rom
j3 17:b646b1e3970b 188 result = OWWriteBlock(buf, 1 + RomId::byteLen);
j3 15:f6cb0d906fb6 189 }
j3 17:b646b1e3970b 190
j3 17:b646b1e3970b 191 return result;
j3 15:f6cb0d906fb6 192 }
j3 15:f6cb0d906fb6 193
j3 15:f6cb0d906fb6 194
j3 15:f6cb0d906fb6 195 //*********************************************************************
j3 23:e8e403d61359 196 OneWireMaster::CmdResult OneWireMaster::OWOverdriveSkipROM(void)
j3 15:f6cb0d906fb6 197 {
j3 23:e8e403d61359 198 OneWireMaster::CmdResult result = OWSpeed(SPEED_STANDARD);
j3 15:f6cb0d906fb6 199
j3 23:e8e403d61359 200 if (result == OneWireMaster::Success)
j3 15:f6cb0d906fb6 201 {
j3 17:b646b1e3970b 202 result = OWReset();
j3 15:f6cb0d906fb6 203 }
j3 15:f6cb0d906fb6 204
j3 23:e8e403d61359 205 if (result == OneWireMaster::Success)
j3 17:b646b1e3970b 206 {
IanBenzMaxim 24:8942d8478d68 207 result = OWWriteByte(OVERDRIVE_SKIP_ROM);
j3 17:b646b1e3970b 208 }
j3 17:b646b1e3970b 209
j3 23:e8e403d61359 210 if (result == OneWireMaster::Success)
j3 17:b646b1e3970b 211 {
j3 17:b646b1e3970b 212 result = OWSpeed(SPEED_OVERDRIVE);
j3 17:b646b1e3970b 213 }
j3 17:b646b1e3970b 214
j3 17:b646b1e3970b 215 return result;
j3 15:f6cb0d906fb6 216 }
j3 15:f6cb0d906fb6 217
j3 15:f6cb0d906fb6 218
j3 15:f6cb0d906fb6 219 //*********************************************************************
j3 23:e8e403d61359 220 OneWireMaster::CmdResult OneWireMaster::OWOverdriveMatchROM(const RomId & romId)
j3 15:f6cb0d906fb6 221 {
j3 23:e8e403d61359 222 OneWireMaster::CmdResult result;
j3 15:f6cb0d906fb6 223
j3 17:b646b1e3970b 224 // use overdrive MatchROM
j3 17:b646b1e3970b 225 OWSpeed(SPEED_STANDARD);
j3 17:b646b1e3970b 226
j3 17:b646b1e3970b 227 result = OWReset();
j3 23:e8e403d61359 228 if (result == OneWireMaster::Success)
j3 15:f6cb0d906fb6 229 {
IanBenzMaxim 24:8942d8478d68 230 result = OWWriteByte(OVERDRIVE_MATCH_ROM);
j3 23:e8e403d61359 231 if (result == OneWireMaster::Success)
j3 15:f6cb0d906fb6 232 {
j3 15:f6cb0d906fb6 233 OWSpeed(SPEED_OVERDRIVE);
j3 17:b646b1e3970b 234 // send ROM
j3 17:b646b1e3970b 235 result = OWWriteBlock(romId, RomId::byteLen);
j3 15:f6cb0d906fb6 236 }
j3 15:f6cb0d906fb6 237 }
j3 17:b646b1e3970b 238 return result;
j3 15:f6cb0d906fb6 239 }
j3 15:f6cb0d906fb6 240
j3 15:f6cb0d906fb6 241
j3 15:f6cb0d906fb6 242 //*********************************************************************
j3 23:e8e403d61359 243 OneWireMaster::CmdResult OneWireMaster::OWResume(void)
j3 15:f6cb0d906fb6 244 {
j3 23:e8e403d61359 245 OneWireMaster::CmdResult result;
j3 15:f6cb0d906fb6 246
j3 17:b646b1e3970b 247 result = OWReset();
j3 23:e8e403d61359 248 if (result == OneWireMaster::Success)
j3 15:f6cb0d906fb6 249 {
IanBenzMaxim 24:8942d8478d68 250 result = OWWriteByte(RESUME);
j3 15:f6cb0d906fb6 251 }
j3 15:f6cb0d906fb6 252
j3 17:b646b1e3970b 253 return result;
j3 15:f6cb0d906fb6 254 }
j3 15:f6cb0d906fb6 255
j3 15:f6cb0d906fb6 256
j3 17:b646b1e3970b 257 //--------------------------------------------------------------------------
j3 17:b646b1e3970b 258 // Calculate a new CRC16 from the input data shorteger. Return the current
j3 17:b646b1e3970b 259 // CRC16 and also update the global variable CRC16.
j3 17:b646b1e3970b 260 //
j3 17:b646b1e3970b 261 uint16_t OneWireMaster::calculateCRC16(uint16_t CRC16, uint16_t data)
j3 15:f6cb0d906fb6 262 {
j3 17:b646b1e3970b 263 data = (data ^ (CRC16 & 0xff)) & 0xff;
j3 17:b646b1e3970b 264 CRC16 >>= 8;
j3 17:b646b1e3970b 265
j3 17:b646b1e3970b 266 if (_oddparity[data & 0xf] ^ _oddparity[data >> 4])
j3 17:b646b1e3970b 267 CRC16 ^= 0xc001;
j3 17:b646b1e3970b 268
j3 17:b646b1e3970b 269 data <<= 6;
j3 17:b646b1e3970b 270 CRC16 ^= data;
j3 17:b646b1e3970b 271 data <<= 1;
j3 17:b646b1e3970b 272 CRC16 ^= data;
j3 17:b646b1e3970b 273
j3 17:b646b1e3970b 274 return CRC16;
j3 15:f6cb0d906fb6 275 }
j3 15:f6cb0d906fb6 276
j3 17:b646b1e3970b 277 uint16_t OneWireMaster::calculateCRC16(const uint8_t * data, size_t data_offset, size_t data_len, uint16_t crc)
j3 17:b646b1e3970b 278 {
j3 17:b646b1e3970b 279 for (size_t i = data_offset; i < (data_len + data_offset); i++)
j3 17:b646b1e3970b 280 crc = calculateCRC16(crc, data[i]);
j3 17:b646b1e3970b 281 return crc;
IanBenzMaxim 21:00c94aeb533e 282 }