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