Implementation of 1-Wire with added Alarm Search Functionality

Dependents:   Max32630_One_Wire_Interface

Committer:
IanBenzMaxim
Date:
Mon Mar 21 14:12:28 2016 -0500
Revision:
21:00c94aeb533e
Parent:
17:b646b1e3970b
Child:
23:e8e403d61359
Added class for DS2465. Added a ReadBytePower operation to OneWireMaster since this is required by the authenticators including the DS28E15. Tweaked member data of OneWireMaster. Added path to header file includes to reduce compiler setup required.

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