Руслан Бредун
/
stm32-sensor-base2
test
DS1820/OneWire/OneWire.cpp@11:32eeb052cda5, 2020-08-26 (annotated)
- Committer:
- ommpy
- Date:
- Wed Aug 26 14:26:27 2020 +0530
- Revision:
- 11:32eeb052cda5
added temp sensor in code
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ommpy | 11:32eeb052cda5 | 1 | /* |
ommpy | 11:32eeb052cda5 | 2 | Copyright (c) 2007, Jim Studt (original old version - many contributors since) |
ommpy | 11:32eeb052cda5 | 3 | |
ommpy | 11:32eeb052cda5 | 4 | The latest version of this library may be found at: |
ommpy | 11:32eeb052cda5 | 5 | http://www.pjrc.com/teensy/td_libs_Onehtml |
ommpy | 11:32eeb052cda5 | 6 | |
ommpy | 11:32eeb052cda5 | 7 | OneWire has been maintained by Paul Stoffregen (paul@pjrc.com) since |
ommpy | 11:32eeb052cda5 | 8 | January 2010. At the time, it was in need of many bug fixes, but had |
ommpy | 11:32eeb052cda5 | 9 | been abandoned the original author (Jim Studt). None of the known |
ommpy | 11:32eeb052cda5 | 10 | contributors were interested in maintaining One Paul typically |
ommpy | 11:32eeb052cda5 | 11 | works on OneWire every 6 to 12 months. Patches usually wait that |
ommpy | 11:32eeb052cda5 | 12 | long. If anyone is interested in more actively maintaining OneWire, |
ommpy | 11:32eeb052cda5 | 13 | please contact Paul. |
ommpy | 11:32eeb052cda5 | 14 | |
ommpy | 11:32eeb052cda5 | 15 | Version 2.2: |
ommpy | 11:32eeb052cda5 | 16 | Teensy 3.0 compatibility, Paul Stoffregen, paul@pjrc.com |
ommpy | 11:32eeb052cda5 | 17 | Arduino Due compatibility, http://arduino.cc/forum/index.php?topic=141030 |
ommpy | 11:32eeb052cda5 | 18 | Fix DS18B20 example negative temperature |
ommpy | 11:32eeb052cda5 | 19 | Fix DS18B20 example's low res modes, Ken Butcher |
ommpy | 11:32eeb052cda5 | 20 | Improve reset timing, Mark Tillotson |
ommpy | 11:32eeb052cda5 | 21 | Add const qualifiers, Bertrik Sikken |
ommpy | 11:32eeb052cda5 | 22 | Add initial value input to crc16, Bertrik Sikken |
ommpy | 11:32eeb052cda5 | 23 | Add target_search() function, Scott Roberts |
ommpy | 11:32eeb052cda5 | 24 | |
ommpy | 11:32eeb052cda5 | 25 | Version 2.1: |
ommpy | 11:32eeb052cda5 | 26 | Arduino 1.0 compatibility, Paul Stoffregen |
ommpy | 11:32eeb052cda5 | 27 | Improve temperature example, Paul Stoffregen |
ommpy | 11:32eeb052cda5 | 28 | DS250x_PROM example, Guillermo Lovato |
ommpy | 11:32eeb052cda5 | 29 | PIC32 (chipKit) compatibility, Jason Dangel, dangel.jason AT gmail.com |
ommpy | 11:32eeb052cda5 | 30 | Improvements from Glenn Trewitt: |
ommpy | 11:32eeb052cda5 | 31 | - crc16() now works |
ommpy | 11:32eeb052cda5 | 32 | - check_crc16() does all of calculation/checking work. |
ommpy | 11:32eeb052cda5 | 33 | - Added read_bytes() and write_bytes(), to reduce tedious loops. |
ommpy | 11:32eeb052cda5 | 34 | - Added ds2408 example. |
ommpy | 11:32eeb052cda5 | 35 | Delete very old, out-of-date readme file (info is here) |
ommpy | 11:32eeb052cda5 | 36 | |
ommpy | 11:32eeb052cda5 | 37 | Version 2.0: Modifications by Paul Stoffregen, January 2010: |
ommpy | 11:32eeb052cda5 | 38 | http://www.pjrc.com/teensy/td_libs_Onehtml |
ommpy | 11:32eeb052cda5 | 39 | Search fix from Robin James |
ommpy | 11:32eeb052cda5 | 40 | http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295/27#27 |
ommpy | 11:32eeb052cda5 | 41 | Use direct optimized I/O in all cases |
ommpy | 11:32eeb052cda5 | 42 | Disable interrupts during timing critical sections |
ommpy | 11:32eeb052cda5 | 43 | (this solves many random communication errors) |
ommpy | 11:32eeb052cda5 | 44 | Disable interrupts during read-modify-write I/O |
ommpy | 11:32eeb052cda5 | 45 | Reduce RAM consumption by eliminating unnecessary |
ommpy | 11:32eeb052cda5 | 46 | variables and trimming many to 8 bits |
ommpy | 11:32eeb052cda5 | 47 | Optimize both crc8 - table version moved to flash |
ommpy | 11:32eeb052cda5 | 48 | |
ommpy | 11:32eeb052cda5 | 49 | Modified to work with larger numbers of devices - avoids loop. |
ommpy | 11:32eeb052cda5 | 50 | Tested in Arduino 11 alpha with 12 sensors. |
ommpy | 11:32eeb052cda5 | 51 | 26 Sept 2008 -- Robin James |
ommpy | 11:32eeb052cda5 | 52 | http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295/27#27 |
ommpy | 11:32eeb052cda5 | 53 | |
ommpy | 11:32eeb052cda5 | 54 | Updated to work with arduino-0008 and to include skip() as of |
ommpy | 11:32eeb052cda5 | 55 | 2007/07/06. --RJL20 |
ommpy | 11:32eeb052cda5 | 56 | |
ommpy | 11:32eeb052cda5 | 57 | Modified to calculate the 8-bit CRC directly, avoiding the need for |
ommpy | 11:32eeb052cda5 | 58 | the 256-byte lookup table to be loaded in RAM. Tested in arduino-0010 |
ommpy | 11:32eeb052cda5 | 59 | -- Tom Pollard, Jan 23, 2008 |
ommpy | 11:32eeb052cda5 | 60 | |
ommpy | 11:32eeb052cda5 | 61 | Jim Studt's original library was modified by Josh Larios. |
ommpy | 11:32eeb052cda5 | 62 | |
ommpy | 11:32eeb052cda5 | 63 | Tom Pollard, pollard@alum.mit.edu, contributed around May 20, 2008 |
ommpy | 11:32eeb052cda5 | 64 | |
ommpy | 11:32eeb052cda5 | 65 | Permission is hereby granted, free of charge, to any person obtaining |
ommpy | 11:32eeb052cda5 | 66 | a copy of this software and associated documentation files (the |
ommpy | 11:32eeb052cda5 | 67 | "Software"), to deal in the Software without restriction, including |
ommpy | 11:32eeb052cda5 | 68 | without limitation the rights to use, copy, modify, merge, publish, |
ommpy | 11:32eeb052cda5 | 69 | distribute, sublicense, and/or sell copies of the Software, and to |
ommpy | 11:32eeb052cda5 | 70 | permit persons to whom the Software is furnished to do so, subject to |
ommpy | 11:32eeb052cda5 | 71 | the following conditions: |
ommpy | 11:32eeb052cda5 | 72 | |
ommpy | 11:32eeb052cda5 | 73 | The above copyright notice and this permission notice shall be |
ommpy | 11:32eeb052cda5 | 74 | included in all copies or substantial portions of the Software. |
ommpy | 11:32eeb052cda5 | 75 | |
ommpy | 11:32eeb052cda5 | 76 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
ommpy | 11:32eeb052cda5 | 77 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
ommpy | 11:32eeb052cda5 | 78 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
ommpy | 11:32eeb052cda5 | 79 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
ommpy | 11:32eeb052cda5 | 80 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
ommpy | 11:32eeb052cda5 | 81 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
ommpy | 11:32eeb052cda5 | 82 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
ommpy | 11:32eeb052cda5 | 83 | |
ommpy | 11:32eeb052cda5 | 84 | Much of the code was inspired by Derek Yerger's code, though I don't |
ommpy | 11:32eeb052cda5 | 85 | think much of that remains. In any event that was.. |
ommpy | 11:32eeb052cda5 | 86 | (copyleft) 2006 by Derek Yerger - Free to distribute freely. |
ommpy | 11:32eeb052cda5 | 87 | |
ommpy | 11:32eeb052cda5 | 88 | The CRC code was excerpted and inspired by the Dallas Semiconductor |
ommpy | 11:32eeb052cda5 | 89 | sample code bearing this copyright. |
ommpy | 11:32eeb052cda5 | 90 | //--------------------------------------------------------------------------- |
ommpy | 11:32eeb052cda5 | 91 | // Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved. |
ommpy | 11:32eeb052cda5 | 92 | // |
ommpy | 11:32eeb052cda5 | 93 | // Permission is hereby granted, free of charge, to any person obtaining a |
ommpy | 11:32eeb052cda5 | 94 | // copy of this software and associated documentation files (the "Software"), |
ommpy | 11:32eeb052cda5 | 95 | // to deal in the Software without restriction, including without limitation |
ommpy | 11:32eeb052cda5 | 96 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, |
ommpy | 11:32eeb052cda5 | 97 | // and/or sell copies of the Software, and to permit persons to whom the |
ommpy | 11:32eeb052cda5 | 98 | // Software is furnished to do so, subject to the following conditions: |
ommpy | 11:32eeb052cda5 | 99 | // |
ommpy | 11:32eeb052cda5 | 100 | // The above copyright notice and this permission notice shall be included |
ommpy | 11:32eeb052cda5 | 101 | // in all copies or substantial portions of the Software. |
ommpy | 11:32eeb052cda5 | 102 | // |
ommpy | 11:32eeb052cda5 | 103 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
ommpy | 11:32eeb052cda5 | 104 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
ommpy | 11:32eeb052cda5 | 105 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
ommpy | 11:32eeb052cda5 | 106 | // IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES |
ommpy | 11:32eeb052cda5 | 107 | // OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
ommpy | 11:32eeb052cda5 | 108 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
ommpy | 11:32eeb052cda5 | 109 | // OTHER DEALINGS IN THE SOFTWARE. |
ommpy | 11:32eeb052cda5 | 110 | // |
ommpy | 11:32eeb052cda5 | 111 | // Except as contained in this notice, the name of Dallas Semiconductor |
ommpy | 11:32eeb052cda5 | 112 | // shall not be used except as stated in the Dallas Semiconductor |
ommpy | 11:32eeb052cda5 | 113 | // Branding Policy. |
ommpy | 11:32eeb052cda5 | 114 | //-------------------------------------------------------------------------- |
ommpy | 11:32eeb052cda5 | 115 | */ |
ommpy | 11:32eeb052cda5 | 116 | #include "OneWire.h" |
ommpy | 11:32eeb052cda5 | 117 | |
ommpy | 11:32eeb052cda5 | 118 | |
ommpy | 11:32eeb052cda5 | 119 | /** |
ommpy | 11:32eeb052cda5 | 120 | * @brief Constructs a OneWire object. |
ommpy | 11:32eeb052cda5 | 121 | * @note GPIO is configured as output and an internal pull up resistor is connected. |
ommpy | 11:32eeb052cda5 | 122 | * But because for STM chips it takes very long time to change from output |
ommpy | 11:32eeb052cda5 | 123 | * to input an open drain mode is used rather and the GPIO remains output forever. |
ommpy | 11:32eeb052cda5 | 124 | * @param |
ommpy | 11:32eeb052cda5 | 125 | * @retval |
ommpy | 11:32eeb052cda5 | 126 | */ |
ommpy | 11:32eeb052cda5 | 127 | OneWire::OneWire(PinName pin, int sample_point_us /* = 13 */) : |
ommpy | 11:32eeb052cda5 | 128 | DigitalInOut(pin), |
ommpy | 11:32eeb052cda5 | 129 | _sample_point_us(sample_point_us) |
ommpy | 11:32eeb052cda5 | 130 | { |
ommpy | 11:32eeb052cda5 | 131 | Timer timer; |
ommpy | 11:32eeb052cda5 | 132 | |
ommpy | 11:32eeb052cda5 | 133 | MODE(); // set mode to either OpenDrain for STM or PullUp for others |
ommpy | 11:32eeb052cda5 | 134 | |
ommpy | 11:32eeb052cda5 | 135 | // Measure bus transition time from ouput to input |
ommpy | 11:32eeb052cda5 | 136 | timer.reset(); |
ommpy | 11:32eeb052cda5 | 137 | OUTPUT(); // set as output |
ommpy | 11:32eeb052cda5 | 138 | WRITE(0); // pull the line down |
ommpy | 11:32eeb052cda5 | 139 | timer.start(); |
ommpy | 11:32eeb052cda5 | 140 | INPUT(); // set as input (and release the bus) |
ommpy | 11:32eeb052cda5 | 141 | timer.stop(); |
ommpy | 11:32eeb052cda5 | 142 | _out_to_in_transition_us = timer.read_us(); |
ommpy | 11:32eeb052cda5 | 143 | |
ommpy | 11:32eeb052cda5 | 144 | MBED_ASSERT(_out_to_in_transition_us < _sample_point_us); |
ommpy | 11:32eeb052cda5 | 145 | |
ommpy | 11:32eeb052cda5 | 146 | INIT_WAIT; |
ommpy | 11:32eeb052cda5 | 147 | #if ONEWIRE_SEARCH |
ommpy | 11:32eeb052cda5 | 148 | reset_search(); |
ommpy | 11:32eeb052cda5 | 149 | #endif |
ommpy | 11:32eeb052cda5 | 150 | } |
ommpy | 11:32eeb052cda5 | 151 | |
ommpy | 11:32eeb052cda5 | 152 | /** |
ommpy | 11:32eeb052cda5 | 153 | * @brief Performs the onewire reset function. |
ommpy | 11:32eeb052cda5 | 154 | * @note We will wait up to 250uS for the bus to come high, |
ommpy | 11:32eeb052cda5 | 155 | * if it doesn't then it is broken or shorted and we return a 0; |
ommpy | 11:32eeb052cda5 | 156 | * @param |
ommpy | 11:32eeb052cda5 | 157 | * @retval 1 if a device asserted a presence pulse, 0 otherwise. |
ommpy | 11:32eeb052cda5 | 158 | */ |
ommpy | 11:32eeb052cda5 | 159 | uint8_t OneWire::reset(void) |
ommpy | 11:32eeb052cda5 | 160 | { |
ommpy | 11:32eeb052cda5 | 161 | uint8_t present; |
ommpy | 11:32eeb052cda5 | 162 | |
ommpy | 11:32eeb052cda5 | 163 | OUTPUT(); |
ommpy | 11:32eeb052cda5 | 164 | WRITE(0); // pull down the 1-wire bus do create reset pulse |
ommpy | 11:32eeb052cda5 | 165 | WAIT_US(500); // wait at least 480 us |
ommpy | 11:32eeb052cda5 | 166 | INPUT(); // release the 1-wire bus and go into receive mode |
ommpy | 11:32eeb052cda5 | 167 | WAIT_US(90); // DS1820 waits about 15 to 60 us and generates a 60 to 240 us presence pulse |
ommpy | 11:32eeb052cda5 | 168 | present = !READ(); // read the presence pulse |
ommpy | 11:32eeb052cda5 | 169 | WAIT_US(420); |
ommpy | 11:32eeb052cda5 | 170 | |
ommpy | 11:32eeb052cda5 | 171 | return present; |
ommpy | 11:32eeb052cda5 | 172 | } |
ommpy | 11:32eeb052cda5 | 173 | |
ommpy | 11:32eeb052cda5 | 174 | /** |
ommpy | 11:32eeb052cda5 | 175 | * @brief Writes a bit. |
ommpy | 11:32eeb052cda5 | 176 | * @note GPIO registers are used for STM chips to cut time. |
ommpy | 11:32eeb052cda5 | 177 | * @param |
ommpy | 11:32eeb052cda5 | 178 | * @retval |
ommpy | 11:32eeb052cda5 | 179 | */ |
ommpy | 11:32eeb052cda5 | 180 | void OneWire::write_bit(uint8_t v) |
ommpy | 11:32eeb052cda5 | 181 | { |
ommpy | 11:32eeb052cda5 | 182 | OUTPUT(); |
ommpy | 11:32eeb052cda5 | 183 | if (v & 1) { |
ommpy | 11:32eeb052cda5 | 184 | WRITE(0); // drive output low |
ommpy | 11:32eeb052cda5 | 185 | WAIT_US(1); |
ommpy | 11:32eeb052cda5 | 186 | WRITE(1); // drive output high |
ommpy | 11:32eeb052cda5 | 187 | WAIT_US(60); |
ommpy | 11:32eeb052cda5 | 188 | } |
ommpy | 11:32eeb052cda5 | 189 | else { |
ommpy | 11:32eeb052cda5 | 190 | WRITE(0); // drive output low |
ommpy | 11:32eeb052cda5 | 191 | WAIT_US(60); |
ommpy | 11:32eeb052cda5 | 192 | WRITE(1); // drive output high |
ommpy | 11:32eeb052cda5 | 193 | WAIT_US(1); |
ommpy | 11:32eeb052cda5 | 194 | } |
ommpy | 11:32eeb052cda5 | 195 | } |
ommpy | 11:32eeb052cda5 | 196 | |
ommpy | 11:32eeb052cda5 | 197 | /** |
ommpy | 11:32eeb052cda5 | 198 | * @brief Reads a bit. |
ommpy | 11:32eeb052cda5 | 199 | * @note GPIO registers are used for STM chips to cut time. |
ommpy | 11:32eeb052cda5 | 200 | * @param |
ommpy | 11:32eeb052cda5 | 201 | * @retval |
ommpy | 11:32eeb052cda5 | 202 | */ |
ommpy | 11:32eeb052cda5 | 203 | uint8_t OneWire::read_bit(void) |
ommpy | 11:32eeb052cda5 | 204 | { |
ommpy | 11:32eeb052cda5 | 205 | uint8_t r; |
ommpy | 11:32eeb052cda5 | 206 | |
ommpy | 11:32eeb052cda5 | 207 | OUTPUT(); |
ommpy | 11:32eeb052cda5 | 208 | WRITE(0); |
ommpy | 11:32eeb052cda5 | 209 | INPUT(); |
ommpy | 11:32eeb052cda5 | 210 | wait_us(_sample_point_us - _out_to_in_transition_us); // wait till sample point |
ommpy | 11:32eeb052cda5 | 211 | r = READ(); |
ommpy | 11:32eeb052cda5 | 212 | WAIT_US(55); |
ommpy | 11:32eeb052cda5 | 213 | return r; |
ommpy | 11:32eeb052cda5 | 214 | } |
ommpy | 11:32eeb052cda5 | 215 | |
ommpy | 11:32eeb052cda5 | 216 | /** |
ommpy | 11:32eeb052cda5 | 217 | * @brief Writes a byte. |
ommpy | 11:32eeb052cda5 | 218 | * @note The writing code uses the active drivers to raise the |
ommpy | 11:32eeb052cda5 | 219 | pin high, if you need power after the write (e.g. DS18S20 in |
ommpy | 11:32eeb052cda5 | 220 | parasite power mode) then set 'power' to 1, otherwise the pin will |
ommpy | 11:32eeb052cda5 | 221 | go tri-state at the end of the write to avoid heating in a short or |
ommpy | 11:32eeb052cda5 | 222 | other mishap. |
ommpy | 11:32eeb052cda5 | 223 | * @param |
ommpy | 11:32eeb052cda5 | 224 | * @retval |
ommpy | 11:32eeb052cda5 | 225 | */ |
ommpy | 11:32eeb052cda5 | 226 | void OneWire::write_byte(uint8_t v, uint8_t power /* = 0 */ ) |
ommpy | 11:32eeb052cda5 | 227 | { |
ommpy | 11:32eeb052cda5 | 228 | uint8_t bitMask; |
ommpy | 11:32eeb052cda5 | 229 | |
ommpy | 11:32eeb052cda5 | 230 | for (bitMask = 0x01; bitMask; bitMask <<= 1) |
ommpy | 11:32eeb052cda5 | 231 | write_bit((bitMask & v) ? 1 : 0); |
ommpy | 11:32eeb052cda5 | 232 | if (!power) |
ommpy | 11:32eeb052cda5 | 233 | INPUT(); |
ommpy | 11:32eeb052cda5 | 234 | } |
ommpy | 11:32eeb052cda5 | 235 | |
ommpy | 11:32eeb052cda5 | 236 | /** |
ommpy | 11:32eeb052cda5 | 237 | * @brief Writes bytes. |
ommpy | 11:32eeb052cda5 | 238 | * @note |
ommpy | 11:32eeb052cda5 | 239 | * @param |
ommpy | 11:32eeb052cda5 | 240 | * @retval |
ommpy | 11:32eeb052cda5 | 241 | */ |
ommpy | 11:32eeb052cda5 | 242 | void OneWire::write_bytes(const uint8_t* buf, uint16_t count, bool power /* = 0 */ ) |
ommpy | 11:32eeb052cda5 | 243 | { |
ommpy | 11:32eeb052cda5 | 244 | for (uint16_t i = 0; i < count; i++) |
ommpy | 11:32eeb052cda5 | 245 | write_byte(buf[i]); |
ommpy | 11:32eeb052cda5 | 246 | if (!power) |
ommpy | 11:32eeb052cda5 | 247 | INPUT(); |
ommpy | 11:32eeb052cda5 | 248 | } |
ommpy | 11:32eeb052cda5 | 249 | |
ommpy | 11:32eeb052cda5 | 250 | /** |
ommpy | 11:32eeb052cda5 | 251 | * @brief Reads a byte. |
ommpy | 11:32eeb052cda5 | 252 | * @note |
ommpy | 11:32eeb052cda5 | 253 | * @param |
ommpy | 11:32eeb052cda5 | 254 | * @retval |
ommpy | 11:32eeb052cda5 | 255 | */ |
ommpy | 11:32eeb052cda5 | 256 | uint8_t OneWire::read_byte() |
ommpy | 11:32eeb052cda5 | 257 | { |
ommpy | 11:32eeb052cda5 | 258 | uint8_t bitMask; |
ommpy | 11:32eeb052cda5 | 259 | uint8_t r = 0; |
ommpy | 11:32eeb052cda5 | 260 | |
ommpy | 11:32eeb052cda5 | 261 | for (bitMask = 0x01; bitMask; bitMask <<= 1) { |
ommpy | 11:32eeb052cda5 | 262 | if (read_bit()) |
ommpy | 11:32eeb052cda5 | 263 | r |= bitMask; |
ommpy | 11:32eeb052cda5 | 264 | } |
ommpy | 11:32eeb052cda5 | 265 | |
ommpy | 11:32eeb052cda5 | 266 | return r; |
ommpy | 11:32eeb052cda5 | 267 | } |
ommpy | 11:32eeb052cda5 | 268 | |
ommpy | 11:32eeb052cda5 | 269 | /** |
ommpy | 11:32eeb052cda5 | 270 | * @brief Reads bytes. |
ommpy | 11:32eeb052cda5 | 271 | * @note |
ommpy | 11:32eeb052cda5 | 272 | * @param |
ommpy | 11:32eeb052cda5 | 273 | * @retval |
ommpy | 11:32eeb052cda5 | 274 | */ |
ommpy | 11:32eeb052cda5 | 275 | void OneWire::read_bytes(uint8_t* buf, uint16_t count) |
ommpy | 11:32eeb052cda5 | 276 | { |
ommpy | 11:32eeb052cda5 | 277 | for (uint16_t i = 0; i < count; i++) |
ommpy | 11:32eeb052cda5 | 278 | buf[i] = read_byte(); |
ommpy | 11:32eeb052cda5 | 279 | } |
ommpy | 11:32eeb052cda5 | 280 | |
ommpy | 11:32eeb052cda5 | 281 | /** |
ommpy | 11:32eeb052cda5 | 282 | * @brief Selects ROM. |
ommpy | 11:32eeb052cda5 | 283 | * @note |
ommpy | 11:32eeb052cda5 | 284 | * @param |
ommpy | 11:32eeb052cda5 | 285 | * @retval |
ommpy | 11:32eeb052cda5 | 286 | */ |
ommpy | 11:32eeb052cda5 | 287 | void OneWire::select(const uint8_t rom[8]) |
ommpy | 11:32eeb052cda5 | 288 | { |
ommpy | 11:32eeb052cda5 | 289 | uint8_t i; |
ommpy | 11:32eeb052cda5 | 290 | |
ommpy | 11:32eeb052cda5 | 291 | write_byte(0x55); // Choose ROM |
ommpy | 11:32eeb052cda5 | 292 | for (i = 0; i < 8; i++) |
ommpy | 11:32eeb052cda5 | 293 | write_byte(rom[i]); |
ommpy | 11:32eeb052cda5 | 294 | } |
ommpy | 11:32eeb052cda5 | 295 | |
ommpy | 11:32eeb052cda5 | 296 | /** |
ommpy | 11:32eeb052cda5 | 297 | * @brief Skips ROM select. |
ommpy | 11:32eeb052cda5 | 298 | * @note |
ommpy | 11:32eeb052cda5 | 299 | * @param |
ommpy | 11:32eeb052cda5 | 300 | * @retval |
ommpy | 11:32eeb052cda5 | 301 | */ |
ommpy | 11:32eeb052cda5 | 302 | void OneWire::skip() |
ommpy | 11:32eeb052cda5 | 303 | { |
ommpy | 11:32eeb052cda5 | 304 | write_byte(0xCC); // Skip ROM |
ommpy | 11:32eeb052cda5 | 305 | } |
ommpy | 11:32eeb052cda5 | 306 | |
ommpy | 11:32eeb052cda5 | 307 | /** |
ommpy | 11:32eeb052cda5 | 308 | * @brief Unpowers the chip. |
ommpy | 11:32eeb052cda5 | 309 | * @note |
ommpy | 11:32eeb052cda5 | 310 | * @param |
ommpy | 11:32eeb052cda5 | 311 | * @retval |
ommpy | 11:32eeb052cda5 | 312 | */ |
ommpy | 11:32eeb052cda5 | 313 | void OneWire::depower() |
ommpy | 11:32eeb052cda5 | 314 | { |
ommpy | 11:32eeb052cda5 | 315 | INPUT(); |
ommpy | 11:32eeb052cda5 | 316 | } |
ommpy | 11:32eeb052cda5 | 317 | |
ommpy | 11:32eeb052cda5 | 318 | #if ONEWIRE_SEARCH |
ommpy | 11:32eeb052cda5 | 319 | // |
ommpy | 11:32eeb052cda5 | 320 | |
ommpy | 11:32eeb052cda5 | 321 | /** |
ommpy | 11:32eeb052cda5 | 322 | * @brief Resets the search state. |
ommpy | 11:32eeb052cda5 | 323 | * @note We need to use this function to start a search again from the beginning. |
ommpy | 11:32eeb052cda5 | 324 | * We do not need to do it for the first search, though we could. |
ommpy | 11:32eeb052cda5 | 325 | * @param |
ommpy | 11:32eeb052cda5 | 326 | * @retval |
ommpy | 11:32eeb052cda5 | 327 | */ |
ommpy | 11:32eeb052cda5 | 328 | void OneWire::reset_search() |
ommpy | 11:32eeb052cda5 | 329 | { |
ommpy | 11:32eeb052cda5 | 330 | // reset the search state |
ommpy | 11:32eeb052cda5 | 331 | LastDiscrepancy = 0; |
ommpy | 11:32eeb052cda5 | 332 | LastDeviceFlag = false; |
ommpy | 11:32eeb052cda5 | 333 | LastFamilyDiscrepancy = 0; |
ommpy | 11:32eeb052cda5 | 334 | for (int i = 7;; i--) { |
ommpy | 11:32eeb052cda5 | 335 | ROM_NO[i] = 0; |
ommpy | 11:32eeb052cda5 | 336 | if (i == 0) |
ommpy | 11:32eeb052cda5 | 337 | break; |
ommpy | 11:32eeb052cda5 | 338 | } |
ommpy | 11:32eeb052cda5 | 339 | } |
ommpy | 11:32eeb052cda5 | 340 | |
ommpy | 11:32eeb052cda5 | 341 | /** |
ommpy | 11:32eeb052cda5 | 342 | * @brief Sets the search state to find SearchFamily type devices. |
ommpy | 11:32eeb052cda5 | 343 | * @note |
ommpy | 11:32eeb052cda5 | 344 | * @param |
ommpy | 11:32eeb052cda5 | 345 | * @retval |
ommpy | 11:32eeb052cda5 | 346 | */ |
ommpy | 11:32eeb052cda5 | 347 | void OneWire::target_search(uint8_t family_code) |
ommpy | 11:32eeb052cda5 | 348 | { |
ommpy | 11:32eeb052cda5 | 349 | // set the search state to find SearchFamily type devices |
ommpy | 11:32eeb052cda5 | 350 | ROM_NO[0] = family_code; |
ommpy | 11:32eeb052cda5 | 351 | for (uint8_t i = 1; i < 8; i++) |
ommpy | 11:32eeb052cda5 | 352 | ROM_NO[i] = 0; |
ommpy | 11:32eeb052cda5 | 353 | LastDiscrepancy = 64; |
ommpy | 11:32eeb052cda5 | 354 | LastFamilyDiscrepancy = 0; |
ommpy | 11:32eeb052cda5 | 355 | LastDeviceFlag = false; |
ommpy | 11:32eeb052cda5 | 356 | } |
ommpy | 11:32eeb052cda5 | 357 | |
ommpy | 11:32eeb052cda5 | 358 | /** |
ommpy | 11:32eeb052cda5 | 359 | * @brief Performs a search. |
ommpy | 11:32eeb052cda5 | 360 | * @note Perform a search. If this function returns a '1' then it has |
ommpy | 11:32eeb052cda5 | 361 | enumerated the next device and you may retrieve the ROM from the |
ommpy | 11:32eeb052cda5 | 362 | OneWire::address variable. If there are no devices, no further |
ommpy | 11:32eeb052cda5 | 363 | devices, or something horrible happens in the middle of the |
ommpy | 11:32eeb052cda5 | 364 | enumeration then a 0 is returned. If a new device is found then |
ommpy | 11:32eeb052cda5 | 365 | its address is copied to newAddr. Use OneWire::reset_search() to |
ommpy | 11:32eeb052cda5 | 366 | start over. |
ommpy | 11:32eeb052cda5 | 367 | |
ommpy | 11:32eeb052cda5 | 368 | --- Replaced by the one from the Dallas Semiconductor web site --- |
ommpy | 11:32eeb052cda5 | 369 | ------------------------------------------------------------------------- |
ommpy | 11:32eeb052cda5 | 370 | Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing |
ommpy | 11:32eeb052cda5 | 371 | search state. |
ommpy | 11:32eeb052cda5 | 372 | * @param |
ommpy | 11:32eeb052cda5 | 373 | * @retval true : device found, ROM number in ROM_NO buffer |
ommpy | 11:32eeb052cda5 | 374 | * false : device not found, end of search |
ommpy | 11:32eeb052cda5 | 375 | */ |
ommpy | 11:32eeb052cda5 | 376 | uint8_t OneWire::search(uint8_t* newAddr) |
ommpy | 11:32eeb052cda5 | 377 | { |
ommpy | 11:32eeb052cda5 | 378 | uint8_t id_bit_number; |
ommpy | 11:32eeb052cda5 | 379 | uint8_t last_zero, rom_byte_number, search_result; |
ommpy | 11:32eeb052cda5 | 380 | uint8_t id_bit, cmp_id_bit; |
ommpy | 11:32eeb052cda5 | 381 | |
ommpy | 11:32eeb052cda5 | 382 | unsigned char rom_byte_mask, search_direction; |
ommpy | 11:32eeb052cda5 | 383 | |
ommpy | 11:32eeb052cda5 | 384 | // initialize for search |
ommpy | 11:32eeb052cda5 | 385 | id_bit_number = 1; |
ommpy | 11:32eeb052cda5 | 386 | last_zero = 0; |
ommpy | 11:32eeb052cda5 | 387 | rom_byte_number = 0; |
ommpy | 11:32eeb052cda5 | 388 | rom_byte_mask = 1; |
ommpy | 11:32eeb052cda5 | 389 | search_result = 0; |
ommpy | 11:32eeb052cda5 | 390 | |
ommpy | 11:32eeb052cda5 | 391 | // if the last call was not the last one |
ommpy | 11:32eeb052cda5 | 392 | if (!LastDeviceFlag) { |
ommpy | 11:32eeb052cda5 | 393 | // 1-Wire reset |
ommpy | 11:32eeb052cda5 | 394 | if (!reset()) { |
ommpy | 11:32eeb052cda5 | 395 | // reset the search |
ommpy | 11:32eeb052cda5 | 396 | LastDiscrepancy = 0; |
ommpy | 11:32eeb052cda5 | 397 | LastDeviceFlag = false; |
ommpy | 11:32eeb052cda5 | 398 | LastFamilyDiscrepancy = 0; |
ommpy | 11:32eeb052cda5 | 399 | return false; |
ommpy | 11:32eeb052cda5 | 400 | } |
ommpy | 11:32eeb052cda5 | 401 | |
ommpy | 11:32eeb052cda5 | 402 | // issue the search command |
ommpy | 11:32eeb052cda5 | 403 | write_byte(0xF0); |
ommpy | 11:32eeb052cda5 | 404 | |
ommpy | 11:32eeb052cda5 | 405 | // loop to do the search |
ommpy | 11:32eeb052cda5 | 406 | do { |
ommpy | 11:32eeb052cda5 | 407 | // read a bit and its complement |
ommpy | 11:32eeb052cda5 | 408 | id_bit = read_bit(); |
ommpy | 11:32eeb052cda5 | 409 | cmp_id_bit = read_bit(); |
ommpy | 11:32eeb052cda5 | 410 | |
ommpy | 11:32eeb052cda5 | 411 | // check for no devices on 1-wire |
ommpy | 11:32eeb052cda5 | 412 | if ((id_bit == 1) && (cmp_id_bit == 1)) |
ommpy | 11:32eeb052cda5 | 413 | break; |
ommpy | 11:32eeb052cda5 | 414 | else { |
ommpy | 11:32eeb052cda5 | 415 | // all devices coupled have 0 or 1 |
ommpy | 11:32eeb052cda5 | 416 | if (id_bit != cmp_id_bit) |
ommpy | 11:32eeb052cda5 | 417 | search_direction = id_bit; // bit write value for search |
ommpy | 11:32eeb052cda5 | 418 | else { |
ommpy | 11:32eeb052cda5 | 419 | // if this discrepancy if before the Last Discrepancy |
ommpy | 11:32eeb052cda5 | 420 | // on a previous next then pick the same as last time |
ommpy | 11:32eeb052cda5 | 421 | if (id_bit_number < LastDiscrepancy) |
ommpy | 11:32eeb052cda5 | 422 | search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0); |
ommpy | 11:32eeb052cda5 | 423 | else |
ommpy | 11:32eeb052cda5 | 424 | // if equal to last pick 1, if not then pick 0 |
ommpy | 11:32eeb052cda5 | 425 | search_direction = (id_bit_number == LastDiscrepancy); |
ommpy | 11:32eeb052cda5 | 426 | |
ommpy | 11:32eeb052cda5 | 427 | // if 0 was picked then record its position in LastZero |
ommpy | 11:32eeb052cda5 | 428 | if (search_direction == 0) { |
ommpy | 11:32eeb052cda5 | 429 | last_zero = id_bit_number; |
ommpy | 11:32eeb052cda5 | 430 | |
ommpy | 11:32eeb052cda5 | 431 | // check for Last discrepancy in family |
ommpy | 11:32eeb052cda5 | 432 | if (last_zero < 9) |
ommpy | 11:32eeb052cda5 | 433 | LastFamilyDiscrepancy = last_zero; |
ommpy | 11:32eeb052cda5 | 434 | } |
ommpy | 11:32eeb052cda5 | 435 | } |
ommpy | 11:32eeb052cda5 | 436 | |
ommpy | 11:32eeb052cda5 | 437 | // set or clear the bit in the ROM byte rom_byte_number |
ommpy | 11:32eeb052cda5 | 438 | // with mask rom_byte_mask |
ommpy | 11:32eeb052cda5 | 439 | if (search_direction == 1) |
ommpy | 11:32eeb052cda5 | 440 | ROM_NO[rom_byte_number] |= rom_byte_mask; |
ommpy | 11:32eeb052cda5 | 441 | else |
ommpy | 11:32eeb052cda5 | 442 | ROM_NO[rom_byte_number] &= ~rom_byte_mask; |
ommpy | 11:32eeb052cda5 | 443 | |
ommpy | 11:32eeb052cda5 | 444 | // serial number search direction write bit |
ommpy | 11:32eeb052cda5 | 445 | write_bit(search_direction); |
ommpy | 11:32eeb052cda5 | 446 | |
ommpy | 11:32eeb052cda5 | 447 | // increment the byte counter id_bit_number |
ommpy | 11:32eeb052cda5 | 448 | // and shift the mask rom_byte_mask |
ommpy | 11:32eeb052cda5 | 449 | id_bit_number++; |
ommpy | 11:32eeb052cda5 | 450 | rom_byte_mask <<= 1; |
ommpy | 11:32eeb052cda5 | 451 | |
ommpy | 11:32eeb052cda5 | 452 | // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask |
ommpy | 11:32eeb052cda5 | 453 | if (rom_byte_mask == 0) { |
ommpy | 11:32eeb052cda5 | 454 | rom_byte_number++; |
ommpy | 11:32eeb052cda5 | 455 | rom_byte_mask = 1; |
ommpy | 11:32eeb052cda5 | 456 | } |
ommpy | 11:32eeb052cda5 | 457 | } |
ommpy | 11:32eeb052cda5 | 458 | } while (rom_byte_number < 8); |
ommpy | 11:32eeb052cda5 | 459 | // loop until through all ROM bytes 0-7 |
ommpy | 11:32eeb052cda5 | 460 | // if the search was successful then |
ommpy | 11:32eeb052cda5 | 461 | if (!(id_bit_number < 65)) { |
ommpy | 11:32eeb052cda5 | 462 | // search successful so set LastDiscrepancy,LastDeviceFlag,search_result |
ommpy | 11:32eeb052cda5 | 463 | LastDiscrepancy = last_zero; |
ommpy | 11:32eeb052cda5 | 464 | |
ommpy | 11:32eeb052cda5 | 465 | // check for last device |
ommpy | 11:32eeb052cda5 | 466 | if (LastDiscrepancy == 0) |
ommpy | 11:32eeb052cda5 | 467 | LastDeviceFlag = true; |
ommpy | 11:32eeb052cda5 | 468 | |
ommpy | 11:32eeb052cda5 | 469 | search_result = true; |
ommpy | 11:32eeb052cda5 | 470 | } |
ommpy | 11:32eeb052cda5 | 471 | } |
ommpy | 11:32eeb052cda5 | 472 | |
ommpy | 11:32eeb052cda5 | 473 | // if no device found then reset counters so next 'search' will be like a first |
ommpy | 11:32eeb052cda5 | 474 | if (!search_result || !ROM_NO[0]) { |
ommpy | 11:32eeb052cda5 | 475 | LastDiscrepancy = 0; |
ommpy | 11:32eeb052cda5 | 476 | LastDeviceFlag = false; |
ommpy | 11:32eeb052cda5 | 477 | LastFamilyDiscrepancy = 0; |
ommpy | 11:32eeb052cda5 | 478 | search_result = false; |
ommpy | 11:32eeb052cda5 | 479 | } |
ommpy | 11:32eeb052cda5 | 480 | |
ommpy | 11:32eeb052cda5 | 481 | for (int i = 0; i < 8; i++) |
ommpy | 11:32eeb052cda5 | 482 | newAddr[i] = ROM_NO[i]; |
ommpy | 11:32eeb052cda5 | 483 | return search_result; |
ommpy | 11:32eeb052cda5 | 484 | } |
ommpy | 11:32eeb052cda5 | 485 | #endif |
ommpy | 11:32eeb052cda5 | 486 | // |
ommpy | 11:32eeb052cda5 | 487 | #if ONEWIRE_CRC |
ommpy | 11:32eeb052cda5 | 488 | // |
ommpy | 11:32eeb052cda5 | 489 | /** |
ommpy | 11:32eeb052cda5 | 490 | * @brief Computes a Dallas Semiconductor 8 bit CRC directly. |
ommpy | 11:32eeb052cda5 | 491 | * @note The 1-Wire CRC scheme is described in Maxim Application Note 27: |
ommpy | 11:32eeb052cda5 | 492 | "Understanding and Using Cyclic Redundancy Checks with Maxim iButton Products" |
ommpy | 11:32eeb052cda5 | 493 | * @param |
ommpy | 11:32eeb052cda5 | 494 | * @retval |
ommpy | 11:32eeb052cda5 | 495 | */ |
ommpy | 11:32eeb052cda5 | 496 | uint8_t OneWire::crc8(const uint8_t* addr, uint8_t len) |
ommpy | 11:32eeb052cda5 | 497 | { |
ommpy | 11:32eeb052cda5 | 498 | uint8_t crc = 0; |
ommpy | 11:32eeb052cda5 | 499 | |
ommpy | 11:32eeb052cda5 | 500 | while (len--) { |
ommpy | 11:32eeb052cda5 | 501 | uint8_t inbyte = *addr++; |
ommpy | 11:32eeb052cda5 | 502 | for (uint8_t i = 8; i; i--) { |
ommpy | 11:32eeb052cda5 | 503 | uint8_t mix = (crc ^ inbyte) & 0x01; |
ommpy | 11:32eeb052cda5 | 504 | crc >>= 1; |
ommpy | 11:32eeb052cda5 | 505 | if (mix) |
ommpy | 11:32eeb052cda5 | 506 | crc ^= 0x8C; |
ommpy | 11:32eeb052cda5 | 507 | inbyte >>= 1; |
ommpy | 11:32eeb052cda5 | 508 | } |
ommpy | 11:32eeb052cda5 | 509 | } |
ommpy | 11:32eeb052cda5 | 510 | |
ommpy | 11:32eeb052cda5 | 511 | return crc; |
ommpy | 11:32eeb052cda5 | 512 | } |
ommpy | 11:32eeb052cda5 | 513 | #endif |