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
DS2480B.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/DS2480B/DS2480B.h" 00034 #include "Serial.h" 00035 #include "Timer.h" 00036 #include "wait_api.h" 00037 00038 // Mode Commands 00039 #define MODE_DATA 0xE1 00040 #define MODE_COMMAND 0xE3 00041 #define MODE_STOP_PULSE 0xF1 00042 00043 // Return byte value 00044 #define RB_CHIPID_MASK 0x1C 00045 #define RB_RESET_MASK 0x03 00046 #define RB_1WIRESHORT 0x00 00047 #define RB_PRESENCE 0x01 00048 #define RB_ALARMPRESENCE 0x02 00049 #define RB_NOPRESENCE 0x03 00050 00051 #define RB_BIT_MASK 0x03 00052 #define RB_BIT_ONE 0x03 00053 #define RB_BIT_ZERO 0x00 00054 00055 // Masks for all bit ranges 00056 #define CMD_MASK 0x80 00057 #define FUNCTSEL_MASK 0x60 00058 #define BITPOL_MASK 0x10 00059 #define SPEEDSEL_MASK 0x0C 00060 #define MODSEL_MASK 0x02 00061 #define PARMSEL_MASK 0x70 00062 #define PARMSET_MASK 0x0E 00063 00064 // Command or config bit 00065 #define CMD_COMM 0x81 00066 #define CMD_CONFIG 0x01 00067 00068 // Function select bits 00069 #define FUNCTSEL_BIT 0x00 00070 #define FUNCTSEL_SEARCHON 0x30 00071 #define FUNCTSEL_SEARCHOFF 0x20 00072 #define FUNCTSEL_RESET 0x40 00073 #define FUNCTSEL_CHMOD 0x60 00074 00075 // Bit polarity/Pulse voltage bits 00076 #define BITPOL_ONE 0x10 00077 #define BITPOL_ZERO 0x00 00078 #define BITPOL_5V 0x00 00079 #define BITPOL_12V 0x10 00080 00081 // One Wire speed bits 00082 #define SPEEDSEL_STD 0x00 00083 #define SPEEDSEL_FLEX 0x04 00084 #define SPEEDSEL_OD 0x08 00085 #define SPEEDSEL_PULSE 0x0C 00086 00087 // Data/Command mode select bits 00088 #define MODSEL_DATA 0x00 00089 #define MODSEL_COMMAND 0x02 00090 00091 // 5V Follow Pulse select bits 00092 #define PRIME5V_TRUE 0x02 00093 #define PRIME5V_FALSE 0x00 00094 00095 // Parameter select bits 00096 #define PARMSEL_PARMREAD 0x00 00097 #define PARMSEL_SLEW 0x10 00098 #define PARMSEL_12VPULSE 0x20 00099 #define PARMSEL_5VPULSE 0x30 00100 #define PARMSEL_WRITE1LOW 0x40 00101 #define PARMSEL_SAMPLEOFFSET 0x50 00102 #define PARMSEL_ACTIVEPULLUPTIME 0x60 00103 #define PARMSEL_BAUDRATE 0x70 00104 00105 // Pull down slew rate. 00106 #define PARMSET_Slew15Vus 0x00 00107 #define PARMSET_Slew2p2Vus 0x02 00108 #define PARMSET_Slew1p65Vus 0x04 00109 #define PARMSET_Slew1p37Vus 0x06 00110 #define PARMSET_Slew1p1Vus 0x08 00111 #define PARMSET_Slew0p83Vus 0x0A 00112 #define PARMSET_Slew0p7Vus 0x0C 00113 #define PARMSET_Slew0p55Vus 0x0E 00114 00115 // 12V programming pulse time table 00116 #define PARMSET_32us 0x00 00117 #define PARMSET_64us 0x02 00118 #define PARMSET_128us 0x04 00119 #define PARMSET_256us 0x06 00120 #define PARMSET_512us 0x08 00121 #define PARMSET_1024us 0x0A 00122 #define PARMSET_2048us 0x0C 00123 #define PARMSET_infinite 0x0E 00124 00125 // 5V strong pull up pulse time table 00126 #define PARMSET_16p4ms 0x00 00127 #define PARMSET_65p5ms 0x02 00128 #define PARMSET_131ms 0x04 00129 #define PARMSET_262ms 0x06 00130 #define PARMSET_524ms 0x08 00131 #define PARMSET_1p05s 0x0A 00132 #define PARMSET_dynamic 0x0C 00133 #define PARMSET_infinite 0x0E 00134 00135 // Write 1 low time 00136 #define PARMSET_Write8us 0x00 00137 #define PARMSET_Write9us 0x02 00138 #define PARMSET_Write10us 0x04 00139 #define PARMSET_Write11us 0x06 00140 #define PARMSET_Write12us 0x08 00141 #define PARMSET_Write13us 0x0A 00142 #define PARMSET_Write14us 0x0C 00143 #define PARMSET_Write15us 0x0E 00144 00145 // Data sample offset and Write 0 recovery time 00146 #define PARMSET_SampOff3us 0x00 00147 #define PARMSET_SampOff4us 0x02 00148 #define PARMSET_SampOff5us 0x04 00149 #define PARMSET_SampOff6us 0x06 00150 #define PARMSET_SampOff7us 0x08 00151 #define PARMSET_SampOff8us 0x0A 00152 #define PARMSET_SampOff9us 0x0C 00153 #define PARMSET_SampOff10us 0x0E 00154 00155 // Active pull up on time 00156 #define PARMSET_PullUp0p0us 0x00 00157 #define PARMSET_PullUp0p5us 0x02 00158 #define PARMSET_PullUp1p0us 0x04 00159 #define PARMSET_PullUp1p5us 0x06 00160 #define PARMSET_PullUp2p0us 0x08 00161 #define PARMSET_PullUp2p5us 0x0A 00162 #define PARMSET_PullUp3p0us 0x0C 00163 #define PARMSET_PullUp3p5us 0x0E 00164 00165 // DS2480B program voltage available 00166 #define DS2480BPROG_MASK 0x20 00167 00168 using OneWire::DS2480B; 00169 using OneWire::OneWireMaster; 00170 00171 static uint32_t calculateBitTimeout(DS2480B::BaudRate baud) 00172 { 00173 // Calculate bit timeout in microsecond. 00174 // 10x the time needed to transmit or receive. 00175 // Double for 115200 due to timer inaccuracies. 00176 00177 //*100 for 10 bits/byte and ten times the time needed 00178 00179 uint32_t timeout = 1000000 * 100; 00180 00181 switch (baud) 00182 { 00183 case DS2480B::Baud115200bps: 00184 timeout = (timeout * 2) / 115200; 00185 break; 00186 00187 case DS2480B::Baud57600bps: 00188 timeout /= 57600; 00189 break; 00190 00191 case DS2480B::Baud19200bps: 00192 timeout /= 19200; 00193 break; 00194 00195 case DS2480B::Baud9600bps: 00196 default: 00197 timeout /= 9600; 00198 break; 00199 } 00200 00201 return timeout; 00202 } 00203 00204 DS2480B::DS2480B(PinName tx, PinName rx) 00205 : serial(tx, rx) 00206 { 00207 00208 } 00209 00210 OneWireMaster::CmdResult DS2480B::OWInitMaster() 00211 { 00212 return detect(); 00213 } 00214 00215 OneWireMaster::CmdResult DS2480B::OWReset() 00216 { 00217 OneWireMaster::CmdResult result; 00218 00219 uint8_t readbuffer[10], sendpacket[10]; 00220 uint8_t sendlen = 0; 00221 00222 // make sure normal level 00223 result = OWSetLevel(OneWireMaster::NormalLevel); 00224 if (result == OneWireMaster::Success) 00225 { 00226 // check for correct mode 00227 if (mode != MODSEL_COMMAND) 00228 { 00229 mode = MODSEL_COMMAND; 00230 sendpacket[sendlen++] = MODE_COMMAND; 00231 } 00232 00233 // construct the command 00234 sendpacket[sendlen++] = (uint8_t)(CMD_COMM | FUNCTSEL_RESET | speed); 00235 00236 // flush the buffers 00237 flushCom(); 00238 00239 // send the packet 00240 result = writeCom(sendlen, sendpacket); 00241 if (result == OneWireMaster::Success) 00242 { 00243 // read back the 1 byte response 00244 result = readCom(1, readbuffer); 00245 if (result == OneWireMaster::Success) 00246 { 00247 // make sure this byte looks like a reset byte 00248 if (((readbuffer[0] & RB_RESET_MASK) == RB_PRESENCE) || ((readbuffer[0] & RB_RESET_MASK) == RB_ALARMPRESENCE)) 00249 { 00250 result = OneWireMaster::Success; 00251 } 00252 else 00253 { 00254 result = OneWireMaster::OperationFailure; 00255 } 00256 } 00257 } 00258 } 00259 00260 return result; 00261 } 00262 00263 OneWireMaster::CmdResult DS2480B::OWTouchBitSetLevel(uint8_t & sendRecvBit, OWLevel afterLevel) 00264 { 00265 OneWireMaster::CmdResult result = OneWireMaster::OperationFailure; 00266 00267 uint8_t readbuffer[10], sendpacket[10]; 00268 uint8_t sendlen = 0; 00269 00270 // make sure normal level 00271 OWSetLevel(OneWireMaster::NormalLevel); 00272 00273 // check for correct mode 00274 if (mode != MODSEL_COMMAND) 00275 { 00276 mode = MODSEL_COMMAND; 00277 sendpacket[sendlen++] = MODE_COMMAND; 00278 } 00279 00280 // construct the command 00281 sendpacket[sendlen] = (sendRecvBit != 0) ? BITPOL_ONE : BITPOL_ZERO; 00282 sendpacket[sendlen++] |= CMD_COMM | FUNCTSEL_BIT | speed; 00283 00284 // flush the buffers 00285 flushCom(); 00286 00287 // send the packet 00288 result = writeCom(sendlen, sendpacket); 00289 if (result == OneWireMaster::Success) 00290 { 00291 // read back the response 00292 result = readCom(1, readbuffer); 00293 if (result == OneWireMaster::Success) 00294 { 00295 // interpret the response 00296 if (((readbuffer[0] & 0xE0) == 0x80) && ((readbuffer[0] & RB_BIT_MASK) == RB_BIT_ONE)) 00297 { 00298 sendRecvBit = 1; 00299 result = OneWireMaster::Success; 00300 } 00301 else 00302 { 00303 sendRecvBit = 0; 00304 result = OneWireMaster::Success; 00305 } 00306 } 00307 else 00308 { 00309 result = OneWireMaster::CommunicationReadError; 00310 } 00311 } 00312 else 00313 { 00314 result = OneWireMaster::CommunicationWriteError; 00315 } 00316 00317 if (result == OneWireMaster::Success) 00318 { 00319 result = OWSetLevel(afterLevel); 00320 } 00321 00322 return result; 00323 } 00324 00325 OneWireMaster::CmdResult DS2480B::OWWriteByteSetLevel(uint8_t sendByte, OWLevel afterLevel) 00326 { 00327 OneWireMaster::CmdResult result = OneWireMaster::OperationFailure; 00328 00329 uint8_t readbuffer[10], sendpacket[10]; 00330 uint8_t sendlen = 0; 00331 00332 // make sure normal level 00333 OWSetLevel(OneWireMaster::NormalLevel); 00334 00335 // check for correct mode 00336 if (mode != MODSEL_DATA) 00337 { 00338 mode = MODSEL_DATA; 00339 sendpacket[sendlen++] = MODE_DATA; 00340 } 00341 00342 // add the byte to send 00343 sendpacket[sendlen++] = sendByte; 00344 00345 // check for duplication of data that looks like COMMAND mode 00346 if (sendByte == MODE_COMMAND) 00347 { 00348 sendpacket[sendlen++] = sendByte; 00349 } 00350 00351 // flush the buffers 00352 flushCom(); 00353 00354 // send the packet 00355 result = writeCom(sendlen, sendpacket); 00356 if (result == OneWireMaster::Success) 00357 { 00358 // read back the 1 byte response 00359 result = readCom(1, readbuffer); 00360 if ((result == OneWireMaster::Success) && (readbuffer[0] == sendByte)) 00361 { 00362 result = OneWireMaster::Success; 00363 } 00364 else 00365 { 00366 result = OneWireMaster::CommunicationReadError; 00367 } 00368 } 00369 else 00370 { 00371 result = OneWireMaster::CommunicationWriteError; 00372 } 00373 00374 if (result == OneWireMaster::Success) 00375 { 00376 result = OWSetLevel(afterLevel); 00377 } 00378 00379 return result; 00380 } 00381 00382 OneWireMaster::CmdResult DS2480B::OWReadByteSetLevel(uint8_t & recvByte, OWLevel afterLevel) 00383 { 00384 OneWireMaster::CmdResult result = OneWireMaster::OperationFailure; 00385 00386 uint8_t readbuffer[10], sendpacket[10]; 00387 uint8_t sendlen = 0; 00388 00389 // make sure normal level 00390 OWSetLevel(OneWireMaster::NormalLevel); 00391 00392 // check for correct mode 00393 if (mode != MODSEL_DATA) 00394 { 00395 mode = MODSEL_DATA; 00396 sendpacket[sendlen++] = MODE_DATA; 00397 } 00398 00399 // add the byte to send 00400 sendpacket[sendlen++] = 0xFF; 00401 00402 // flush the buffers 00403 flushCom(); 00404 00405 // send the packet 00406 result = writeCom(sendlen, sendpacket); 00407 if (result == OneWireMaster::Success) 00408 { 00409 // read back the 1 byte response 00410 result = readCom(1, readbuffer); 00411 if (result == OneWireMaster::Success) 00412 { 00413 recvByte = readbuffer[0]; 00414 result = OneWireMaster::Success; 00415 } 00416 else 00417 { 00418 result = OneWireMaster::CommunicationReadError; 00419 } 00420 } 00421 else 00422 { 00423 result = OneWireMaster::CommunicationWriteError; 00424 } 00425 00426 // an error occured so re-sync with DS2480B 00427 if (result == OneWireMaster::Success) 00428 { 00429 result = OWSetLevel(afterLevel); 00430 } 00431 00432 return result; 00433 } 00434 00435 OneWireMaster::CmdResult DS2480B::OWSetSpeed(OWSpeed newSpeed) 00436 { 00437 OneWireMaster::CmdResult result = OneWireMaster::OperationFailure; 00438 00439 uint8_t sendpacket[5]; 00440 uint8_t sendlen = 0; 00441 00442 // check if change from current mode 00443 if (((newSpeed == OneWireMaster::OverdriveSpeed) && (speed != SPEEDSEL_OD)) || 00444 ((newSpeed == OneWireMaster::StandardSpeed) && (speed != SPEEDSEL_STD))) 00445 { 00446 if (newSpeed == OneWireMaster::OverdriveSpeed) 00447 { 00448 result = changeBaud(Baud115200bps); 00449 if (result == OneWireMaster::Success) 00450 { 00451 speed = SPEEDSEL_OD; 00452 } 00453 } 00454 else if (newSpeed == OneWireMaster::StandardSpeed) 00455 { 00456 result = changeBaud(Baud9600bps); 00457 if (result == OneWireMaster::Success) 00458 { 00459 speed = SPEEDSEL_STD; 00460 } 00461 } 00462 00463 // if baud rate is set correctly then change DS2480 speed 00464 if (result == OneWireMaster::Success) 00465 { 00466 // check if correct mode 00467 if (mode != MODSEL_COMMAND) 00468 { 00469 mode = MODSEL_COMMAND; 00470 sendpacket[sendlen++] = MODE_COMMAND; 00471 } 00472 00473 // proceed to set the DS2480 communication speed 00474 sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_SEARCHOFF | speed; 00475 00476 // send the packet 00477 result = writeCom(sendlen,sendpacket); 00478 } 00479 } 00480 00481 return result; 00482 } 00483 00484 OneWireMaster::CmdResult DS2480B::OWSetLevel(OWLevel newLevel) 00485 { 00486 OneWireMaster::CmdResult result = OneWireMaster::Success; 00487 00488 uint8_t sendpacket[10], readbuffer[10]; 00489 uint8_t sendlen = 0; 00490 00491 // check if need to change level 00492 if (newLevel != level) 00493 { 00494 // check for correct mode 00495 if (mode != MODSEL_COMMAND) 00496 { 00497 mode = MODSEL_COMMAND; 00498 sendpacket[sendlen++] = MODE_COMMAND; 00499 } 00500 00501 // check if just putting back to normal 00502 if (newLevel == OneWireMaster::NormalLevel) 00503 { 00504 // stop pulse command 00505 sendpacket[sendlen++] = MODE_STOP_PULSE; 00506 00507 // add the command to begin the pulse WITHOUT prime 00508 sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_CHMOD | SPEEDSEL_PULSE | BITPOL_5V | PRIME5V_FALSE; 00509 00510 // stop pulse command 00511 sendpacket[sendlen++] = MODE_STOP_PULSE; 00512 00513 // flush the buffers 00514 flushCom(); 00515 00516 // send the packet 00517 result = writeCom(sendlen, sendpacket); 00518 if (result == OneWireMaster::Success) 00519 { 00520 // read back the 1 byte response 00521 result = readCom(2, readbuffer); 00522 if (result == OneWireMaster::Success) 00523 { 00524 // check response byte 00525 if (((readbuffer[0] & 0xE0) == 0xE0) && ((readbuffer[1] & 0xE0) == 0xE0)) 00526 { 00527 level = OneWireMaster::NormalLevel; 00528 } 00529 else 00530 { 00531 result = OneWireMaster::OperationFailure; 00532 } 00533 } 00534 } 00535 } 00536 // set new level 00537 else 00538 { 00539 // set the SPUD time value 00540 sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_5VPULSE | PARMSET_infinite; 00541 // add the command to begin the pulse 00542 sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_CHMOD | SPEEDSEL_PULSE | BITPOL_5V; 00543 00544 // flush the buffers 00545 flushCom(); 00546 00547 // send the packet 00548 result = writeCom(sendlen, sendpacket); 00549 if (result == OneWireMaster::Success) 00550 { 00551 // read back the 1 byte response from setting time limit 00552 result = readCom(1, readbuffer); 00553 if (result == OneWireMaster::Success) 00554 { 00555 // check response byte 00556 if ((readbuffer[0] & 0x81) == 0) 00557 { 00558 level = newLevel; 00559 } 00560 else 00561 { 00562 result = OneWireMaster::OperationFailure; 00563 } 00564 } 00565 } 00566 } 00567 } 00568 00569 return result; 00570 } 00571 00572 OneWireMaster::CmdResult DS2480B::detect() 00573 { 00574 OneWireMaster::CmdResult result; 00575 00576 uint8_t sendpacket[10], readbuffer[10]; 00577 uint8_t sendlen = 0; 00578 00579 // reset modes 00580 level = OneWireMaster::NormalLevel; 00581 mode = MODSEL_COMMAND; 00582 baud = Baud9600bps; 00583 speed = SPEEDSEL_FLEX; 00584 00585 // set the baud rate to 9600 00586 setComBaud(baud); 00587 00588 // send a break to reset the DS2480B 00589 breakCom(); 00590 00591 // delay to let line settle 00592 wait_ms(2); 00593 00594 // flush the buffers 00595 flushCom(); 00596 00597 // send the timing byte 00598 sendpacket[0] = 0xC1; 00599 result = writeCom(1, sendpacket); 00600 if (result == OneWireMaster::Success) 00601 { 00602 // delay to let line settle 00603 wait_ms(2); 00604 00605 // set the FLEX configuration parameters 00606 // default PDSRC = 1.37Vus 00607 sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_SLEW | PARMSET_Slew1p37Vus; 00608 // default W1LT = 10us 00609 sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_WRITE1LOW | PARMSET_Write10us; 00610 // default DSO/WORT = 8us 00611 sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_SAMPLEOFFSET | PARMSET_SampOff8us; 00612 00613 // construct the command to read the baud rate (to test command block) 00614 sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_PARMREAD | (PARMSEL_BAUDRATE >> 3); 00615 00616 // also do 1 bit operation (to test 1-Wire block) 00617 sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_BIT | baud | BITPOL_ONE; 00618 00619 // flush the buffers 00620 flushCom(); 00621 00622 // send the packet 00623 result = writeCom(sendlen, sendpacket); 00624 if (result == OneWireMaster::Success) 00625 { 00626 // read back the response 00627 result = readCom(5, readbuffer); 00628 if (result == OneWireMaster::Success) 00629 { 00630 // look at the baud rate and bit operation 00631 // to see if the response makes sense 00632 if (((readbuffer[3] & 0xF1) == 0x00) && ((readbuffer[3] & 0x0E) == baud) && ((readbuffer[4] & 0xF0) == 0x90) && ((readbuffer[4] & 0x0C) == baud)) 00633 { 00634 result = OneWireMaster::Success; 00635 } 00636 else 00637 { 00638 result = OneWireMaster::OperationFailure; 00639 } 00640 } 00641 } 00642 } 00643 00644 return result; 00645 } 00646 00647 OneWireMaster::CmdResult DS2480B::changeBaud(BaudRate newBaud) 00648 { 00649 OneWireMaster::CmdResult result = OneWireMaster::Success; 00650 00651 uint8_t readbuffer[5], sendpacket[5], sendpacket2[5]; 00652 uint8_t sendlen = 0, sendlen2 = 0; 00653 00654 //see if diffenent then current baud rate 00655 if (baud != newBaud) 00656 { 00657 // build the command packet 00658 // check for correct mode 00659 if (mode != MODSEL_COMMAND) 00660 { 00661 mode = MODSEL_COMMAND; 00662 sendpacket[sendlen++] = MODE_COMMAND; 00663 } 00664 // build the command 00665 sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_BAUDRATE | newBaud; 00666 00667 // flush the buffers 00668 flushCom(); 00669 00670 // send the packet 00671 result = writeCom(sendlen, sendpacket); 00672 if (result == OneWireMaster::Success) 00673 { 00674 // make sure buffer is flushed 00675 wait_ms(5); 00676 00677 // change our baud rate 00678 setComBaud(newBaud); 00679 baud = newBaud; 00680 00681 // wait for things to settle 00682 wait_ms(5); 00683 00684 // build a command packet to read back baud rate 00685 sendpacket2[sendlen2++] = CMD_CONFIG | PARMSEL_PARMREAD | (PARMSEL_BAUDRATE >> 3); 00686 00687 // flush the buffers 00688 flushCom(); 00689 00690 // send the packet 00691 result = writeCom(sendlen2, sendpacket2); 00692 if (result == OneWireMaster::Success) 00693 { 00694 // read back the 1 byte response 00695 result = readCom(1, readbuffer); 00696 if (result == OneWireMaster::Success) 00697 { 00698 // verify correct baud 00699 if ((readbuffer[0] & 0x0E) == (sendpacket[sendlen - 1] & 0x0E)) 00700 { 00701 result = OneWireMaster::Success; 00702 } 00703 else 00704 { 00705 result = OneWireMaster::OperationFailure; 00706 } 00707 } 00708 else 00709 { 00710 result = OneWireMaster::CommunicationReadError; 00711 } 00712 } 00713 else 00714 { 00715 result = OneWireMaster::CommunicationWriteError; 00716 } 00717 } 00718 else 00719 { 00720 result = OneWireMaster::CommunicationWriteError; 00721 } 00722 } 00723 00724 return result; 00725 } 00726 00727 OneWireMaster::CmdResult DS2480B::writeCom(size_t outlen, uint8_t *outbuf) 00728 { 00729 OneWireMaster::CmdResult result = OneWireMaster::OperationFailure; 00730 00731 mbed::Timer timer; 00732 uint32_t timeout = calculateBitTimeout(baud) * outlen; 00733 uint8_t idx = 0; 00734 00735 timer.start(); 00736 do 00737 { 00738 while ((idx < outlen) && serial.writeable()) 00739 { 00740 serial.putc(outbuf[idx++]); 00741 } 00742 00743 } while ((idx < outlen) && (static_cast<unsigned int>(timer.read_us()) < timeout)); 00744 00745 if (idx == outlen) 00746 { 00747 result = OneWireMaster::Success; 00748 } 00749 else 00750 { 00751 result = OneWireMaster::TimeoutError; 00752 } 00753 00754 return result; 00755 } 00756 00757 OneWireMaster::CmdResult DS2480B::readCom(size_t inlen, uint8_t *inbuf) 00758 { 00759 OneWireMaster::CmdResult result; 00760 mbed::Timer timer; 00761 uint32_t num_bytes_read = 0; 00762 uint32_t timeout = (calculateBitTimeout(baud) * inlen); 00763 00764 timer.start(); 00765 do 00766 { 00767 while ((num_bytes_read < inlen) && serial.readable()) 00768 { 00769 inbuf[num_bytes_read++] = serial.getc(); 00770 } 00771 } while ((num_bytes_read < inlen) && (static_cast<unsigned int>(timer.read_us()) < timeout)); 00772 timer.stop(); 00773 00774 if (num_bytes_read == inlen) 00775 { 00776 result = OneWireMaster::Success; 00777 } 00778 else 00779 { 00780 result = OneWireMaster::TimeoutError; 00781 } 00782 00783 return result; 00784 } 00785 00786 void DS2480B::breakCom() 00787 { 00788 // Switch to lower baud rate to ensure break is longer than 2 ms. 00789 serial.baud(4800); 00790 serial.send_break(); 00791 setComBaud(baud); 00792 } 00793 00794 void DS2480B::flushCom() 00795 { 00796 // Clear receive buffer. 00797 while (serial.readable()) 00798 { 00799 serial.getc(); 00800 } 00801 00802 /* No apparent way to clear transmit buffer. 00803 * From the example in AN192 (http://pdfserv.maximintegrated.com/en/an/AN192.pdf), 00804 * the data shouldn't be sent, just aborted and the buffer cleaned out. 00805 * Below is what was used in AN192 example code using windows drivers: 00806 * PurgeComm(ComID, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ); 00807 */ 00808 } 00809 00810 void DS2480B::setComBaud(BaudRate new_baud) 00811 { 00812 switch (new_baud) 00813 { 00814 case Baud115200bps: 00815 serial.baud(115200); 00816 break; 00817 00818 case Baud57600bps: 00819 serial.baud(57600); 00820 break; 00821 00822 case Baud19200bps: 00823 serial.baud(19200); 00824 break; 00825 00826 case Baud9600bps: 00827 default: 00828 serial.baud(9600); 00829 break; 00830 } 00831 }
Generated on Tue Jul 12 2022 15:46:21 by
