Device interface library for multiple platforms including Mbed.
Dependents: DeepCover Embedded Security in IoT MaximInterface MAXREFDES155#
DS2480B.cpp
00001 /******************************************************************************* 00002 * Copyright (C) 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 <MaximInterfaceCore/Error.hpp> 00034 #include "DS2480B.hpp" 00035 00036 #define TRY MaximInterfaceCore_TRY 00037 #define TRY_VALUE MaximInterfaceCore_TRY_VALUE 00038 00039 // Mode Commands 00040 #define MODE_DATA 0xE1 00041 #define MODE_COMMAND 0xE3 00042 #define MODE_STOP_PULSE 0xF1 00043 00044 // Return byte value 00045 #define RB_CHIPID_MASK 0x1C 00046 #define RB_RESET_MASK 0x03 00047 #define RB_1WIRESHORT 0x00 00048 #define RB_PRESENCE 0x01 00049 #define RB_ALARMPRESENCE 0x02 00050 #define RB_NOPRESENCE 0x03 00051 00052 #define RB_BIT_MASK 0x03 00053 #define RB_BIT_ONE 0x03 00054 #define RB_BIT_ZERO 0x00 00055 00056 // Masks for all bit ranges 00057 #define CMD_MASK 0x80 00058 #define FUNCTSEL_MASK 0x60 00059 #define BITPOL_MASK 0x10 00060 #define SPEEDSEL_MASK 0x0C 00061 #define MODSEL_MASK 0x02 00062 #define PARMSEL_MASK 0x70 00063 #define PARMSET_MASK 0x0E 00064 00065 // Command or config bit 00066 #define CMD_COMM 0x81 00067 #define CMD_CONFIG 0x01 00068 00069 // Function select bits 00070 #define FUNCTSEL_BIT 0x00 00071 #define FUNCTSEL_SEARCHON 0x30 00072 #define FUNCTSEL_SEARCHOFF 0x20 00073 #define FUNCTSEL_RESET 0x40 00074 #define FUNCTSEL_CHMOD 0x60 00075 00076 // Bit polarity/Pulse voltage bits 00077 #define BITPOL_ONE 0x10 00078 #define BITPOL_ZERO 0x00 00079 #define BITPOL_5V 0x00 00080 #define BITPOL_12V 0x10 00081 00082 // One Wire speed bits 00083 #define SPEEDSEL_STD 0x00 00084 #define SPEEDSEL_FLEX 0x04 00085 #define SPEEDSEL_OD 0x08 00086 #define SPEEDSEL_PULSE 0x0C 00087 00088 // Data/Command mode select bits 00089 #define MODSEL_DATA 0x00 00090 #define MODSEL_COMMAND 0x02 00091 00092 // 5V Follow Pulse select bits 00093 #define PRIME5V_TRUE 0x02 00094 #define PRIME5V_FALSE 0x00 00095 00096 // Parameter select bits 00097 #define PARMSEL_PARMREAD 0x00 00098 #define PARMSEL_SLEW 0x10 00099 #define PARMSEL_12VPULSE 0x20 00100 #define PARMSEL_5VPULSE 0x30 00101 #define PARMSEL_WRITE1LOW 0x40 00102 #define PARMSEL_SAMPLEOFFSET 0x50 00103 #define PARMSEL_ACTIVEPULLUPTIME 0x60 00104 #define PARMSEL_BAUDRATE 0x70 00105 00106 // Pull down slew rate. 00107 #define PARMSET_Slew15Vus 0x00 00108 #define PARMSET_Slew2p2Vus 0x02 00109 #define PARMSET_Slew1p65Vus 0x04 00110 #define PARMSET_Slew1p37Vus 0x06 00111 #define PARMSET_Slew1p1Vus 0x08 00112 #define PARMSET_Slew0p83Vus 0x0A 00113 #define PARMSET_Slew0p7Vus 0x0C 00114 #define PARMSET_Slew0p55Vus 0x0E 00115 00116 // 12V programming pulse time table 00117 #define PARMSET_32us 0x00 00118 #define PARMSET_64us 0x02 00119 #define PARMSET_128us 0x04 00120 #define PARMSET_256us 0x06 00121 #define PARMSET_512us 0x08 00122 #define PARMSET_1024us 0x0A 00123 #define PARMSET_2048us 0x0C 00124 #define PARMSET_infinite 0x0E 00125 00126 // 5V strong pull up pulse time table 00127 #define PARMSET_16p4ms 0x00 00128 #define PARMSET_65p5ms 0x02 00129 #define PARMSET_131ms 0x04 00130 #define PARMSET_262ms 0x06 00131 #define PARMSET_524ms 0x08 00132 #define PARMSET_1p05s 0x0A 00133 #define PARMSET_dynamic 0x0C 00134 #define PARMSET_infinite 0x0E 00135 00136 // Write 1 low time 00137 #define PARMSET_Write8us 0x00 00138 #define PARMSET_Write9us 0x02 00139 #define PARMSET_Write10us 0x04 00140 #define PARMSET_Write11us 0x06 00141 #define PARMSET_Write12us 0x08 00142 #define PARMSET_Write13us 0x0A 00143 #define PARMSET_Write14us 0x0C 00144 #define PARMSET_Write15us 0x0E 00145 00146 // Data sample offset and Write 0 recovery time 00147 #define PARMSET_SampOff3us 0x00 00148 #define PARMSET_SampOff4us 0x02 00149 #define PARMSET_SampOff5us 0x04 00150 #define PARMSET_SampOff6us 0x06 00151 #define PARMSET_SampOff7us 0x08 00152 #define PARMSET_SampOff8us 0x0A 00153 #define PARMSET_SampOff9us 0x0C 00154 #define PARMSET_SampOff10us 0x0E 00155 00156 // Active pull up on time 00157 #define PARMSET_PullUp0p0us 0x00 00158 #define PARMSET_PullUp0p5us 0x02 00159 #define PARMSET_PullUp1p0us 0x04 00160 #define PARMSET_PullUp1p5us 0x06 00161 #define PARMSET_PullUp2p0us 0x08 00162 #define PARMSET_PullUp2p5us 0x0A 00163 #define PARMSET_PullUp3p0us 0x0C 00164 #define PARMSET_PullUp3p5us 0x0E 00165 00166 // Baud rate bits 00167 #define PARMSET_9600 0x00 00168 #define PARMSET_19200 0x02 00169 #define PARMSET_57600 0x04 00170 #define PARMSET_115200 0x06 00171 00172 // DS2480B program voltage available 00173 #define DS2480BPROG_MASK 0x20 00174 00175 namespace MaximInterfaceDevices { 00176 00177 using namespace Core; 00178 00179 Result<void> DS2480B::initialize() { 00180 level = NormalLevel; 00181 mode = MODSEL_COMMAND; 00182 speed = SPEEDSEL_STD; 00183 00184 // Send a break to reset the DS2480B. 00185 // Switch to lower baud rate to ensure break is longer than 2 ms. 00186 Result<void> result = uart->setBaudRate(4800); 00187 if (!result) { 00188 return result; 00189 } 00190 result = uart->sendBreak(); 00191 if (!result) { 00192 return result; 00193 } 00194 result = uart->setBaudRate(9600); 00195 if (!result) { 00196 return result; 00197 } 00198 00199 // Wait for master reset. 00200 sleep->invoke(1); 00201 00202 // Flush the read buffer. 00203 result = uart->clearReadBuffer(); 00204 if (!result) { 00205 return result; 00206 } 00207 00208 // Send the timing byte. 00209 result = uart->writeByte(CMD_COMM | FUNCTSEL_RESET | SPEEDSEL_STD); 00210 if (!result) { 00211 return result; 00212 } 00213 00214 // Change the DS2480 baud rate. 00215 result = uart->writeByte(CMD_CONFIG | PARMSEL_BAUDRATE | PARMSET_115200); 00216 if (!result) { 00217 return result; 00218 } 00219 00220 // Change our baud rate. 00221 result = uart->setBaudRate(115200); 00222 if (!result) { 00223 return result; 00224 } 00225 00226 // Verify response. 00227 uint_least8_t response; 00228 TRY_VALUE(response, uart->readByte()); 00229 if ((response & (PARMSEL_MASK | PARMSET_MASK)) != 00230 (PARMSEL_BAUDRATE | PARMSET_115200)) { 00231 return HardwareError; 00232 } 00233 00234 // Set the SPUD time value. 00235 result = uart->writeByte(CMD_CONFIG | PARMSEL_5VPULSE | PARMSET_infinite); 00236 if (!result) { 00237 return result; 00238 } 00239 00240 // Verify response. 00241 TRY_VALUE(response, uart->readByte()); 00242 if ((response & (PARMSEL_MASK | PARMSET_MASK)) != 00243 (PARMSEL_5VPULSE | PARMSET_infinite)) { 00244 return HardwareError; 00245 } 00246 00247 return result; 00248 } 00249 00250 Result<void> DS2480B::reset() { 00251 if (level != NormalLevel) { 00252 return InvalidLevelError; 00253 } 00254 00255 uint_least8_t packet[2]; 00256 int packetLen = 0; 00257 00258 // Check for correct mode. 00259 if (mode != MODSEL_COMMAND) { 00260 mode = MODSEL_COMMAND; 00261 packet[packetLen++] = MODE_COMMAND; 00262 } 00263 00264 // Construct the command. 00265 packet[packetLen++] = CMD_COMM | FUNCTSEL_RESET | speed; 00266 00267 // Send the packet. 00268 TRY(uart->writeBlock(make_span(packet, packetLen))); 00269 00270 // Read back the response. 00271 TRY_VALUE(packet[0], uart->readByte()); 00272 00273 // Make sure this byte looks like a reset byte. 00274 if ((packet[0] & RB_RESET_MASK) == RB_1WIRESHORT) { 00275 return ShortDetectedError; 00276 } 00277 if ((packet[0] & RB_RESET_MASK) == RB_NOPRESENCE) { 00278 return NoSlaveError; 00279 } 00280 00281 return none; 00282 } 00283 00284 Result<bool> DS2480B::touchBitSetLevel(bool sendBit, Level afterLevel) { 00285 if (level != NormalLevel) { 00286 return InvalidLevelError; 00287 } 00288 00289 uint_least8_t packet[3]; 00290 int packetLen = 0; 00291 00292 // Check for correct mode. 00293 if (mode != MODSEL_COMMAND) { 00294 mode = MODSEL_COMMAND; 00295 packet[packetLen++] = MODE_COMMAND; 00296 } 00297 00298 // Construct the command. 00299 packet[packetLen++] = 00300 CMD_COMM | FUNCTSEL_BIT | (sendBit ? BITPOL_ONE : BITPOL_ZERO) | speed; 00301 switch (afterLevel) { 00302 case NormalLevel: 00303 break; 00304 00305 case StrongLevel: 00306 // Add the command to begin the pulse. 00307 packet[packetLen++] = 00308 CMD_COMM | FUNCTSEL_CHMOD | SPEEDSEL_PULSE | BITPOL_5V | PRIME5V_FALSE; 00309 break; 00310 00311 default: 00312 return InvalidLevelError; 00313 } 00314 00315 // Send the packet. 00316 TRY(uart->writeBlock(make_span(packet, packetLen))); 00317 00318 // Read back the response. 00319 TRY_VALUE(packet[0], uart->readByte()); 00320 00321 // Interpret the response. 00322 if ((packet[0] & 0xE0) != 0x80) { 00323 return HardwareError; 00324 } 00325 level = afterLevel; 00326 return (packet[0] & RB_BIT_MASK) == RB_BIT_ONE; 00327 } 00328 00329 Result<void> DS2480B::writeByteSetLevel(uint_least8_t sendByte, 00330 Level afterLevel) { 00331 if (level != NormalLevel) { 00332 return InvalidLevelError; 00333 } 00334 00335 switch (afterLevel) { 00336 case NormalLevel: 00337 break; 00338 00339 case StrongLevel: 00340 return OneWireMaster::writeByteSetLevel(sendByte, afterLevel); 00341 00342 default: 00343 return InvalidLevelError; 00344 } 00345 00346 uint_least8_t packet[3]; 00347 int packetLen = 0; 00348 00349 // Check for correct mode. 00350 if (mode != MODSEL_DATA) { 00351 mode = MODSEL_DATA; 00352 packet[packetLen++] = MODE_DATA; 00353 } 00354 00355 // Add the byte to send. 00356 packet[packetLen++] = sendByte; 00357 00358 // Check for duplication of data that looks like COMMAND mode. 00359 if (sendByte == MODE_COMMAND) { 00360 packet[packetLen++] = sendByte; 00361 } 00362 00363 // Send the packet. 00364 TRY(uart->writeBlock(make_span(packet, packetLen))); 00365 00366 // Read back the response. 00367 TRY_VALUE(packet[0], uart->readByte()); 00368 00369 // Interpret the response. 00370 if (packet[0] != sendByte) { 00371 return HardwareError; 00372 } 00373 00374 return none; 00375 } 00376 00377 Result<uint_least8_t> DS2480B::readByteSetLevel(Level afterLevel) { 00378 if (level != NormalLevel) { 00379 return InvalidLevelError; 00380 } 00381 00382 switch (afterLevel) { 00383 case NormalLevel: 00384 break; 00385 00386 case StrongLevel: 00387 return OneWireMaster::readByteSetLevel(afterLevel); 00388 00389 default: 00390 return InvalidLevelError; 00391 } 00392 00393 uint_least8_t packet[2]; 00394 int packetLen = 0; 00395 00396 // Check for correct mode. 00397 if (mode != MODSEL_DATA) { 00398 mode = MODSEL_DATA; 00399 packet[packetLen++] = MODE_DATA; 00400 } 00401 00402 // Add the byte to send. 00403 packet[packetLen++] = 0xFF; 00404 00405 // Send the packet. 00406 const Result<void> result = uart->writeBlock(make_span(packet, packetLen)); 00407 if (!result) { 00408 return result.error(); 00409 } 00410 00411 // Read back the response. 00412 return uart->readByte(); 00413 } 00414 00415 Result<void> DS2480B::setSpeed(Speed newSpeed) { 00416 uint_least8_t newSpeedByte; 00417 switch (newSpeed) { 00418 case OverdriveSpeed: 00419 newSpeedByte = SPEEDSEL_OD; 00420 break; 00421 00422 case StandardSpeed: 00423 newSpeedByte = SPEEDSEL_STD; 00424 break; 00425 00426 default: 00427 return InvalidSpeedError; 00428 } 00429 if (speed == newSpeedByte) { 00430 return none; 00431 } 00432 speed = newSpeedByte; 00433 00434 uint_least8_t packet[2]; 00435 int packetLen = 0; 00436 00437 // Check for correct mode. 00438 if (mode != MODSEL_COMMAND) { 00439 mode = MODSEL_COMMAND; 00440 packet[packetLen++] = MODE_COMMAND; 00441 } 00442 00443 // Change DS2480 speed. 00444 packet[packetLen++] = CMD_COMM | FUNCTSEL_SEARCHOFF | speed; 00445 00446 // Send the packet. 00447 return uart->writeBlock(make_span(packet, packetLen)); 00448 } 00449 00450 Result<void> DS2480B::setLevel(Level newLevel) { 00451 if (level == newLevel) { 00452 return none; 00453 } 00454 00455 uint_least8_t packet[2]; 00456 int packetLen = 0; 00457 00458 switch (newLevel) { 00459 case NormalLevel: 00460 // Stop pulse command. 00461 packet[packetLen++] = MODE_STOP_PULSE; 00462 break; 00463 00464 case StrongLevel: 00465 // Check for correct mode. 00466 if (mode != MODSEL_COMMAND) { 00467 mode = MODSEL_COMMAND; 00468 packet[packetLen++] = MODE_COMMAND; 00469 } 00470 00471 // Add the command to begin the pulse. 00472 packet[packetLen++] = 00473 CMD_COMM | FUNCTSEL_CHMOD | SPEEDSEL_PULSE | BITPOL_5V | PRIME5V_FALSE; 00474 break; 00475 00476 default: 00477 return InvalidLevelError; 00478 } 00479 00480 // Send the packet. 00481 TRY(uart->writeBlock(make_span(packet, packetLen))); 00482 00483 if (newLevel == NormalLevel) { 00484 // Read back the response. 00485 TRY_VALUE(packet[0], uart->readByte()); 00486 00487 // Interpret the response. 00488 if ((packet[0] & 0xE0) != 0xE0) { 00489 return HardwareError; 00490 } 00491 } 00492 00493 level = newLevel; 00494 return none; 00495 } 00496 00497 Result<void> DS2480B::sendCommand(uint_least8_t command) { 00498 uint_least8_t packet[2]; 00499 int packetLen = 0; 00500 00501 // Check for correct mode. 00502 if (mode != MODSEL_COMMAND) { 00503 mode = MODSEL_COMMAND; 00504 packet[packetLen++] = MODE_COMMAND; 00505 } 00506 00507 // Add command. 00508 packet[packetLen++] = command; 00509 00510 // Send the packet. 00511 return uart->writeBlock(make_span(packet, packetLen)); 00512 } 00513 00514 const error_category & DS2480B::errorCategory() { 00515 static class : public error_category { 00516 public: 00517 virtual const char * name() const { 00518 return "MaximInterfaceDevices.DS2480B"; 00519 } 00520 00521 virtual std::string message(int condition) const { 00522 switch (condition) { 00523 case HardwareError: 00524 return "Hardware Error"; 00525 } 00526 return defaultErrorMessage(condition); 00527 } 00528 } instance; 00529 return instance; 00530 } 00531 00532 } // namespace MaximInterfaceDevices
Generated on Tue Jul 12 2022 11:13:05 by 1.7.2