Implementation of 1-Wire with added Alarm Search Functionality

Dependents:   Max32630_One_Wire_Interface

Committer:
j3
Date:
Mon Mar 21 23:18:45 2016 +0000
Revision:
23:e8e403d61359
Parent:
21:00c94aeb533e
Child:
24:8942d8478d68
Merged OneWireInterface into OneWireMaster for clarity

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 23:e8e403d61359 41 OneWireMaster::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 23:e8e403d61359 48 OneWireMaster::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 23:e8e403d61359 56 OneWireMaster::CmdResult OneWireMaster::OWTouchByte(uint8_t & sendrecvbyte)
j3 15:f6cb0d906fb6 57 {
j3 23:e8e403d61359 58 OneWireMaster::CmdResult result = OWWriteByte(sendrecvbyte);
j3 17:b646b1e3970b 59
j3 23:e8e403d61359 60 if (result == OneWireMaster::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 23:e8e403d61359 70 OneWireMaster::CmdResult OneWireMaster::OWBlock(uint8_t *tran_buf, uint8_t tran_len)
j3 15:f6cb0d906fb6 71 {
j3 23:e8e403d61359 72 OneWireMaster::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 23:e8e403d61359 78 if (result != OneWireMaster::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 23:e8e403d61359 88 OneWireMaster::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 23:e8e403d61359 100 OneWireMaster::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 23:e8e403d61359 108 OneWireMaster::CmdResult OneWireMaster::OWVerify(const RomId & romId)
j3 15:f6cb0d906fb6 109 {
j3 23:e8e403d61359 110 OneWireMaster::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 23:e8e403d61359 126 if (result == OneWireMaster::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 23:e8e403d61359 131 result = OneWireMaster::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 23:e8e403d61359 178 OneWireMaster::CmdResult OneWireMaster::OWReadROM(RomId & romId)
j3 15:f6cb0d906fb6 179 {
j3 23:e8e403d61359 180 OneWireMaster::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 23:e8e403d61359 185 if (result == OneWireMaster::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 23:e8e403d61359 191 if (result == OneWireMaster::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 23:e8e403d61359 197 if ((result == OneWireMaster::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 23:e8e403d61359 207 OneWireMaster::CmdResult OneWireMaster::OWSkipROM(void)
j3 15:f6cb0d906fb6 208 {
j3 23:e8e403d61359 209 OneWireMaster::CmdResult result;
j3 15:f6cb0d906fb6 210
j3 17:b646b1e3970b 211 result = OWReset();
j3 23:e8e403d61359 212 if (result == OneWireMaster::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 23:e8e403d61359 222 OneWireMaster::CmdResult OneWireMaster::OWMatchROM(const RomId & romId)
j3 15:f6cb0d906fb6 223 {
j3 23:e8e403d61359 224 OneWireMaster::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 23:e8e403d61359 230 if (result == OneWireMaster::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 23:e8e403d61359 243 OneWireMaster::CmdResult OneWireMaster::OWOverdriveSkipROM(void)
j3 15:f6cb0d906fb6 244 {
j3 23:e8e403d61359 245 OneWireMaster::CmdResult result = OWSpeed(SPEED_STANDARD);
j3 15:f6cb0d906fb6 246
j3 23:e8e403d61359 247 if (result == OneWireMaster::Success)
j3 15:f6cb0d906fb6 248 {
j3 17:b646b1e3970b 249 result = OWReset();
j3 15:f6cb0d906fb6 250 }
j3 15:f6cb0d906fb6 251
j3 23:e8e403d61359 252 if (result == OneWireMaster::Success)
j3 17:b646b1e3970b 253 {
j3 17:b646b1e3970b 254 result = OWWriteByte(0x3C);
j3 17:b646b1e3970b 255 }
j3 17:b646b1e3970b 256
j3 23:e8e403d61359 257 if (result == OneWireMaster::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 23:e8e403d61359 267 OneWireMaster::CmdResult OneWireMaster::OWOverdriveMatchROM(const RomId & romId)
j3 15:f6cb0d906fb6 268 {
j3 23:e8e403d61359 269 OneWireMaster::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 23:e8e403d61359 275 if (result == OneWireMaster::Success)
j3 15:f6cb0d906fb6 276 {
j3 17:b646b1e3970b 277 result = OWWriteByte(0x69);
j3 23:e8e403d61359 278 if (result == OneWireMaster::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 23:e8e403d61359 290 OneWireMaster::CmdResult OneWireMaster::OWResume(void)
j3 15:f6cb0d906fb6 291 {
j3 23:e8e403d61359 292 OneWireMaster::CmdResult result;
j3 15:f6cb0d906fb6 293
j3 17:b646b1e3970b 294 result = OWReset();
j3 23:e8e403d61359 295 if (result == OneWireMaster::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 }