Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: MAXREFDES131_Qt_Demo MAX32630FTHR_iButton_uSD_Logger MAX32630FTHR_DS18B20_uSD_Logger MAXREFDES130_131_Demo ... more
DS248x.cpp
00001 /******************************************************************//** 00002 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a 00005 * copy of this software and associated documentation files (the "Software"), 00006 * to deal in the Software without restriction, including without limitation 00007 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00008 * and/or sell copies of the Software, and to permit persons to whom the 00009 * Software is furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included 00012 * in all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00017 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES 00018 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00019 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00020 * OTHER DEALINGS IN THE SOFTWARE. 00021 * 00022 * Except as contained in this notice, the name of Maxim Integrated 00023 * Products, Inc. shall not be used except as stated in the Maxim Integrated 00024 * Products, Inc. Branding Policy. 00025 * 00026 * The mere transfer of this software does not imply any licenses 00027 * of trade secrets, proprietary technology, copyrights, patents, 00028 * trademarks, maskwork rights, or any other form of intellectual 00029 * property whatsoever. Maxim Integrated Products, Inc. retains all 00030 * ownership rights. 00031 **********************************************************************/ 00032 00033 #include "Masters/DS248x/DS248x.h" 00034 #include "I2C.h" 00035 00036 using OneWire::OneWireMaster; 00037 using OneWire::DS248x; 00038 00039 /// DS248x Status Bits 00040 enum StatusBit 00041 { 00042 Status_1WB = 0x01, 00043 Status_PPD = 0x02, 00044 Status_SD = 0x04, 00045 Status_LL = 0x08, 00046 Status_RST = 0x10, 00047 Status_SBR = 0x20, 00048 Status_TSB = 0x40, 00049 Status_DIR = 0x80 00050 }; 00051 00052 static const int I2C_WRITE_OK = 0; 00053 static const int I2C_READ_OK = 0; 00054 00055 uint8_t DS248x::Config::readByte() const 00056 { 00057 uint8_t config = 0; 00058 if (get1WS()) 00059 { 00060 config |= 0x08; 00061 } 00062 if (getSPU()) 00063 { 00064 config |= 0x04; 00065 } 00066 if (getPDN()) 00067 { 00068 config |= 0x02; 00069 } 00070 if (getAPU()) 00071 { 00072 config |= 0x01; 00073 } 00074 return config; 00075 } 00076 00077 uint8_t DS248x::Config::writeByte() const 00078 { 00079 uint8_t config = readByte(); 00080 return ((~config << 4) | config); 00081 } 00082 00083 void DS248x::Config::reset() 00084 { 00085 set1WS(false); 00086 setSPU(false); 00087 setPDN(false); 00088 setAPU(true); 00089 } 00090 00091 00092 DS248x::DS248x(mbed::I2C & i2c_bus, uint8_t adrs): 00093 m_i2c_bus(i2c_bus), m_adrs(adrs) 00094 { 00095 } 00096 00097 00098 OneWireMaster::CmdResult DS248x::OWInitMaster (void) 00099 { 00100 OneWireMaster::CmdResult result; 00101 00102 // reset DS2465 00103 result = reset(); 00104 if (result != OneWireMaster::Success) 00105 { 00106 return result; 00107 } 00108 00109 // write the default configuration setup 00110 Config defaultConfig; 00111 result = writeConfig(defaultConfig, true); 00112 return result; 00113 } 00114 00115 OneWireMaster::CmdResult DS248x::reset(void) 00116 { 00117 // Device Reset 00118 // S AD,0 [A] DRST [A] Sr AD,1 [A] [SS] A\ P 00119 // [] indicates from slave 00120 // SS status byte to read to verify state 00121 00122 OneWireMaster::CmdResult result; 00123 uint8_t buf; 00124 00125 result = sendCommand (DeviceResetCmd); 00126 00127 if (result == OneWireMaster::Success) 00128 { 00129 result = readRegister(StatusReg, buf, true); 00130 } 00131 00132 if (result == OneWireMaster::Success) 00133 { 00134 if ((buf & 0xF7) != 0x10) 00135 { 00136 result = OneWireMaster::OperationFailure; 00137 } 00138 } 00139 00140 if (result == OneWireMaster::Success) 00141 { 00142 OWReset(); // do a command to get 1-Wire master reset out of holding state 00143 } 00144 00145 return result; 00146 } 00147 00148 00149 OneWireMaster::CmdResult DS248x::OWTriplet (SearchDirection & searchDirection, uint8_t & sbr, uint8_t & tsb) 00150 { 00151 // 1-Wire Triplet (Case B) 00152 // S AD,0 [A] 1WT [A] SS [A] Sr AD,1 [A] [Status] A [Status] A\ P 00153 // \--------/ 00154 // Repeat until 1WB bit has changed to 0 00155 // [] indicates from slave 00156 // SS indicates byte containing search direction bit value in msbit 00157 00158 OneWireMaster::CmdResult result; 00159 result = sendCommand (OwTripletCmd, (uint8_t)((searchDirection == WriteOne) ? 0x80 : 0x00)); 00160 if (result == OneWireMaster::Success) 00161 { 00162 uint8_t status; 00163 result = pollBusy(&status); 00164 if (result == OneWireMaster::Success) 00165 { 00166 // check bit results in status byte 00167 sbr = ((status & Status_SBR) == Status_SBR); 00168 tsb = ((status & Status_TSB) == Status_TSB); 00169 searchDirection = ((status & Status_DIR) == Status_DIR) ? WriteOne : WriteZero; 00170 } 00171 } 00172 return result; 00173 } 00174 00175 OneWireMaster::CmdResult DS248x::OWReset() 00176 { 00177 // 1-Wire reset (Case B) 00178 // S AD,0 [A] 1WRS [A] Sr AD,1 [A] [Status] A [Status] A\ P 00179 // \--------/ 00180 // Repeat until 1WB bit has changed to 0 00181 // [] indicates from slave 00182 00183 OneWireMaster::CmdResult result; 00184 uint8_t buf; 00185 00186 result = sendCommand (OwResetCmd); 00187 00188 if (result == OneWireMaster::Success) 00189 { 00190 result = pollBusy(&buf); 00191 } 00192 00193 if (result == OneWireMaster::Success) 00194 { 00195 // check for presence detect 00196 if ((buf & Status_PPD) != Status_PPD) 00197 { 00198 result = OneWireMaster::OperationFailure; 00199 } 00200 } 00201 00202 return result; 00203 } 00204 00205 OneWireMaster::CmdResult DS248x::OWTouchBitSetLevel(uint8_t & sendRecvBit, OWLevel afterLevel) 00206 { 00207 // 1-Wire bit (Case B) 00208 // S AD,0 [A] 1WSB [A] BB [A] Sr AD,1 [A] [Status] A [Status] A\ P 00209 // \--------/ 00210 // Repeat until 1WB bit has changed to 0 00211 // [] indicates from slave 00212 // BB indicates byte containing bit value in msbit 00213 00214 OneWireMaster::CmdResult result; 00215 00216 result = configureLevel(afterLevel); 00217 if (result != OneWireMaster::Success) 00218 { 00219 return result; 00220 } 00221 00222 uint8_t status; 00223 00224 result = sendCommand (OwSingleBitCmd, (uint8_t)(sendRecvBit ? 0x80 : 0x00)); 00225 00226 if (result == OneWireMaster::Success) 00227 { 00228 result = pollBusy(&status); 00229 } 00230 00231 if (result == OneWireMaster::Success) 00232 { 00233 sendRecvBit = (status & Status_SBR); 00234 } 00235 00236 return result; 00237 } 00238 00239 OneWireMaster::CmdResult DS248x::OWWriteByteSetLevel(uint8_t sendByte, OWLevel afterLevel) 00240 { 00241 // 1-Wire Write Byte (Case B) 00242 // S AD,0 [A] 1WWB [A] DD [A] Sr AD,1 [A] [Status] A [Status] A\ P 00243 // \--------/ 00244 // Repeat until 1WB bit has changed to 0 00245 // [] indicates from slave 00246 // DD data to write 00247 00248 OneWireMaster::CmdResult result; 00249 00250 result = configureLevel(afterLevel); 00251 if (result != OneWireMaster::Success) 00252 { 00253 return result; 00254 } 00255 00256 result = sendCommand (OwWriteByteCmd, sendByte); 00257 if (result == OneWireMaster::Success) 00258 { 00259 result = pollBusy(); 00260 } 00261 00262 return result; 00263 } 00264 00265 OneWireMaster::CmdResult DS248x::OWReadByteSetLevel(uint8_t & recvByte, OWLevel afterLevel) 00266 { 00267 // 1-Wire Read Bytes (Case C) 00268 // S AD,0 [A] 1WRB [A] Sr AD,1 [A] [Status] A [Status] A 00269 // \--------/ 00270 // Repeat until 1WB bit has changed to 0 00271 // Sr AD,0 [A] SRP [A] E1 [A] Sr AD,1 [A] DD A\ P 00272 // 00273 // [] indicates from slave 00274 // DD data read 00275 00276 OneWireMaster::CmdResult result; 00277 uint8_t buf; 00278 00279 result = configureLevel(afterLevel); 00280 if (result != OneWireMaster::Success) 00281 { 00282 return result; 00283 } 00284 00285 result = sendCommand (OwReadByteCmd); 00286 00287 if (result == OneWireMaster::Success) 00288 { 00289 result = pollBusy(); 00290 } 00291 00292 if (result == OneWireMaster::Success) 00293 { 00294 result = readRegister(ReadDataReg, buf); 00295 } 00296 00297 if (result == OneWireMaster::Success) 00298 { 00299 recvByte = buf; 00300 } 00301 00302 return result; 00303 } 00304 00305 OneWireMaster::CmdResult DS248x::OWSetSpeed(OWSpeed newSpeed) 00306 { 00307 // Requested speed is already set 00308 if (m_curConfig.get1WS () == (newSpeed == OverdriveSpeed)) 00309 { 00310 return OneWireMaster::Success; 00311 } 00312 00313 // set the speed 00314 Config newConfig = m_curConfig; 00315 newConfig.set1WS(newSpeed == OverdriveSpeed); 00316 00317 // write the new config 00318 return writeConfig(newConfig, true); 00319 } 00320 00321 OneWireMaster::CmdResult DS248x::OWSetLevel(OWLevel newLevel) 00322 { 00323 if (newLevel == StrongLevel) 00324 { 00325 return OneWireMaster::OperationFailure; 00326 } 00327 00328 return configureLevel(newLevel); 00329 } 00330 00331 OneWireMaster::CmdResult DS248x::writeConfig(const Config & config, bool verify) 00332 { 00333 uint8_t configBuf; 00334 OneWireMaster::CmdResult result; 00335 00336 configBuf = config.writeByte(); 00337 result = sendCommand (WriteDeviceConfigCmd, configBuf); 00338 if (verify) 00339 { 00340 if (result == OneWireMaster::Success) 00341 { 00342 result = readRegister(ConfigReg, configBuf); 00343 } 00344 if (result == OneWireMaster::Success) 00345 { 00346 if (configBuf != config.readByte()) 00347 { 00348 result = OneWireMaster::OperationFailure; 00349 } 00350 } 00351 } 00352 00353 if (result == OneWireMaster::Success) 00354 { 00355 m_curConfig = config; 00356 } 00357 00358 return result; 00359 } 00360 00361 OneWireMaster::CmdResult DS248x::readRegister(Register reg, uint8_t & buf, bool skipSetPointer) const 00362 { 00363 CmdResult result = Success; 00364 if (!skipSetPointer) 00365 { 00366 result = sendCommand (SetReadPointerCmd, reg); 00367 } 00368 if (result == Success) 00369 { 00370 if (m_i2c_bus.read(m_adrs, reinterpret_cast<char *>(&buf), 1) != I2C_READ_OK) 00371 { 00372 result = CommunicationReadError; 00373 } 00374 } 00375 return result; 00376 } 00377 00378 OneWireMaster::CmdResult DS248x::pollBusy(uint8_t * pStatus) 00379 { 00380 const unsigned int pollLimit = 200; 00381 00382 OneWireMaster::CmdResult result; 00383 uint8_t status; 00384 unsigned int pollCount = 0; 00385 00386 do 00387 { 00388 result = readRegister(StatusReg, status, true); 00389 if (result != OneWireMaster::Success) 00390 { 00391 return result; 00392 } 00393 if (pStatus != NULL) 00394 { 00395 *pStatus = status; 00396 } 00397 if (pollCount++ >= pollLimit) 00398 { 00399 return OneWireMaster::TimeoutError; 00400 } 00401 } while (status & Status_1WB); 00402 00403 return OneWireMaster::Success; 00404 } 00405 00406 OneWireMaster::CmdResult DS248x::configureLevel(OWLevel level) 00407 { 00408 OneWireMaster::CmdResult result; 00409 if (m_curConfig.getSPU () != (level == StrongLevel)) 00410 { 00411 Config newConfig = m_curConfig; 00412 newConfig.setSPU(level == StrongLevel); 00413 result = writeConfig(newConfig, true); 00414 } 00415 else 00416 { 00417 result = OneWireMaster::Success; 00418 } 00419 return result; 00420 } 00421 00422 OneWireMaster::CmdResult DS248x::sendCommand (Command cmd) const 00423 { 00424 CmdResult result; 00425 if (m_i2c_bus.write(m_adrs, reinterpret_cast<const char *>(&cmd), 1) == I2C_WRITE_OK) 00426 { 00427 result = Success; 00428 } 00429 else 00430 { 00431 result = CommunicationWriteError; 00432 } 00433 return result; 00434 } 00435 00436 OneWireMaster::CmdResult DS248x::sendCommand (Command cmd, uint8_t param) const 00437 { 00438 CmdResult result; 00439 uint8_t buf[2] = { cmd, param }; 00440 if (m_i2c_bus.write(m_adrs, reinterpret_cast<const char *>(buf), 2) == I2C_WRITE_OK) 00441 { 00442 result = Success; 00443 } 00444 else 00445 { 00446 result = CommunicationWriteError; 00447 } 00448 return result; 00449 }
Generated on Tue Jul 12 2022 15:46:21 by
