onewire.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  1. /*
  2. Adaptation of Paul Stoffregen's One wire library to the NodeMcu
  3. The latest version of this library may be found at:
  4. http://www.pjrc.com/teensy/td_libs_OneWire.html
  5. Permission is hereby granted, free of charge, to any person obtaining
  6. a copy of this software and associated documentation files (the
  7. "Software"), to deal in the Software without restriction, including
  8. without limitation the rights to use, copy, modify, merge, publish,
  9. distribute, sublicense, and/or sell copies of the Software, and to
  10. permit persons to whom the Software is furnished to do so, subject to
  11. the following conditions:
  12. The above copyright notice and this permission notice shall be
  13. included in all copies or substantial portions of the Software.
  14. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  15. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  16. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  17. NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  18. LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  19. OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  20. WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. Much of the code was inspired by Derek Yerger's code, though I don't
  22. think much of that remains. In any event that was..
  23. (copyleft) 2006 by Derek Yerger - Free to distribute freely.
  24. The CRC code was excerpted and inspired by the Dallas Semiconductor
  25. sample code bearing this copyright.
  26. //---------------------------------------------------------------------------
  27. // Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved.
  28. //
  29. // Permission is hereby granted, free of charge, to any person obtaining a
  30. // copy of this software and associated documentation files (the "Software"),
  31. // to deal in the Software without restriction, including without limitation
  32. // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  33. // and/or sell copies of the Software, and to permit persons to whom the
  34. // Software is furnished to do so, subject to the following conditions:
  35. //
  36. // The above copyright notice and this permission notice shall be included
  37. // in all copies or substantial portions of the Software.
  38. //
  39. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  40. // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  41. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  42. // IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
  43. // OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  44. // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  45. // OTHER DEALINGS IN THE SOFTWARE.
  46. //
  47. // Except as contained in this notice, the name of Dallas Semiconductor
  48. // shall not be used except as stated in the Dallas Semiconductor
  49. // Branding Policy.
  50. //--------------------------------------------------------------------------
  51. */
  52. #include "driver/onewire.h"
  53. #include "platform.h"
  54. #include "osapi.h"
  55. #define noInterrupts ets_intr_lock
  56. #define interrupts ets_intr_unlock
  57. #define delayMicroseconds os_delay_us
  58. // 1 for keeping the parasitic power on H
  59. #define owDefaultPower 1
  60. #if ONEWIRE_SEARCH
  61. // global search state
  62. static unsigned char ROM_NO[NUM_OW][8];
  63. static uint8_t LastDiscrepancy[NUM_OW];
  64. static uint8_t LastFamilyDiscrepancy[NUM_OW];
  65. static uint8_t LastDeviceFlag[NUM_OW];
  66. #endif
  67. struct onewire_timings_s onewire_timings = {
  68. .reset_tx = 480,
  69. .reset_wait = 70,
  70. .reset_rx = 410,
  71. .w_1_low = 5,
  72. .w_1_high = 52,
  73. .w_0_low = 65,
  74. .w_0_high = 5,
  75. .r_low = 5,
  76. .r_wait = 8,
  77. .r_delay = 52
  78. };
  79. void onewire_init(uint8_t pin)
  80. {
  81. // pinMode(pin, INPUT);
  82. platform_gpio_mode(pin, PLATFORM_GPIO_INPUT, PLATFORM_GPIO_PULLUP);
  83. #if ONEWIRE_SEARCH
  84. onewire_reset_search(pin);
  85. #endif
  86. }
  87. // Perform the onewire reset function. We will wait up to 250uS for
  88. // the bus to come high, if it doesn't then it is broken or shorted
  89. // and we return a 0;
  90. //
  91. // Returns 1 if a device asserted a presence pulse, 0 otherwise.
  92. //
  93. uint8_t onewire_reset(uint8_t pin)
  94. {
  95. uint8_t r;
  96. uint8_t retries = 125;
  97. noInterrupts();
  98. DIRECT_MODE_INPUT(pin);
  99. interrupts();
  100. // wait until the wire is high... just in case
  101. do {
  102. if (--retries == 0) return 0;
  103. delayMicroseconds(2);
  104. } while ( !DIRECT_READ(pin));
  105. noInterrupts();
  106. DIRECT_WRITE_LOW(pin);
  107. interrupts();
  108. delayMicroseconds(onewire_timings.reset_tx);
  109. noInterrupts();
  110. DIRECT_MODE_INPUT(pin); // allow it to float
  111. delayMicroseconds(onewire_timings.reset_wait);
  112. r = !DIRECT_READ(pin);
  113. interrupts();
  114. delayMicroseconds(onewire_timings.reset_rx);
  115. return r;
  116. }
  117. //
  118. // Write a bit. Port and bit is used to cut lookup time and provide
  119. // more certain timing.
  120. //
  121. static void onewire_write_bit(uint8_t pin, uint8_t v, uint8_t power)
  122. {
  123. if (v & 1) {
  124. noInterrupts();
  125. DIRECT_WRITE_LOW(pin);
  126. delayMicroseconds(onewire_timings.w_1_low);
  127. if (power) {
  128. DIRECT_WRITE_HIGH(pin);
  129. } else {
  130. DIRECT_MODE_INPUT(pin); // drive output high by the pull-up
  131. }
  132. delayMicroseconds(8);
  133. interrupts();
  134. delayMicroseconds(onewire_timings.w_1_high);
  135. } else {
  136. noInterrupts();
  137. DIRECT_WRITE_LOW(pin);
  138. delayMicroseconds(onewire_timings.w_0_low);
  139. if (power) {
  140. DIRECT_WRITE_HIGH(pin);
  141. } else {
  142. DIRECT_MODE_INPUT(pin); // drive output high by the pull-up
  143. }
  144. interrupts();
  145. delayMicroseconds(onewire_timings.w_0_high);
  146. }
  147. }
  148. //
  149. // Read a bit. Port and bit is used to cut lookup time and provide
  150. // more certain timing.
  151. //
  152. static uint8_t onewire_read_bit(uint8_t pin)
  153. {
  154. uint8_t r;
  155. noInterrupts();
  156. DIRECT_WRITE_LOW(pin);
  157. delayMicroseconds(onewire_timings.r_low);
  158. DIRECT_MODE_INPUT(pin); // let pin float, pull up will raise
  159. delayMicroseconds(onewire_timings.r_wait);
  160. r = DIRECT_READ(pin);
  161. interrupts();
  162. delayMicroseconds(onewire_timings.r_delay);
  163. return r;
  164. }
  165. //
  166. // Write a byte. The writing code uses the external pull-up to raise the
  167. // pin high, if you need power after the write (e.g. DS18S20 in
  168. // parasite power mode) then set 'power' to 1 and the output driver will
  169. // be activated at the end of the write. Otherwise the pin will
  170. // go tri-state at the end of the write to avoid heating in a short or
  171. // other mishap.
  172. //
  173. void onewire_write(uint8_t pin, uint8_t v, uint8_t power /* = 0 */) {
  174. uint8_t bitMask;
  175. for (bitMask = 0x01; bitMask; bitMask <<= 1) {
  176. // send last bit with requested power mode
  177. onewire_write_bit(pin, (bitMask & v)?1:0, bitMask & 0x80 ? power : 0);
  178. }
  179. }
  180. void onewire_write_bytes(uint8_t pin, const uint8_t *buf, uint16_t count, bool power /* = 0 */) {
  181. uint16_t i;
  182. for (i = 0 ; i < count ; i++)
  183. onewire_write(pin, buf[i], i < count-1 ? owDefaultPower : power);
  184. }
  185. //
  186. // Read a byte
  187. //
  188. uint8_t onewire_read(uint8_t pin) {
  189. uint8_t bitMask;
  190. uint8_t r = 0;
  191. for (bitMask = 0x01; bitMask; bitMask <<= 1) {
  192. if (onewire_read_bit(pin)) r |= bitMask;
  193. }
  194. return r;
  195. }
  196. void onewire_read_bytes(uint8_t pin, uint8_t *buf, uint16_t count) {
  197. uint16_t i;
  198. for (i = 0 ; i < count ; i++)
  199. buf[i] = onewire_read(pin);
  200. }
  201. //
  202. // Do a ROM select
  203. //
  204. void onewire_select(uint8_t pin, const uint8_t rom[8])
  205. {
  206. uint8_t i;
  207. onewire_write(pin, 0x55, owDefaultPower); // Choose ROM
  208. for (i = 0; i < 8; i++) onewire_write(pin, rom[i], owDefaultPower);
  209. }
  210. //
  211. // Do a ROM skip
  212. //
  213. void onewire_skip(uint8_t pin)
  214. {
  215. onewire_write(pin, 0xCC, owDefaultPower); // Skip ROM
  216. }
  217. void onewire_depower(uint8_t pin)
  218. {
  219. noInterrupts();
  220. DIRECT_MODE_INPUT(pin);
  221. interrupts();
  222. }
  223. #if ONEWIRE_SEARCH
  224. //
  225. // You need to use this function to start a search again from the beginning.
  226. // You do not need to do it for the first search, though you could.
  227. //
  228. void onewire_reset_search(uint8_t pin)
  229. {
  230. // reset the search state
  231. LastDiscrepancy[pin] = 0;
  232. LastDeviceFlag[pin] = FALSE;
  233. LastFamilyDiscrepancy[pin] = 0;
  234. int i;
  235. for(i = 7; ; i--) {
  236. ROM_NO[pin][i] = 0;
  237. if ( i == 0) break;
  238. }
  239. }
  240. // Setup the search to find the device type 'family_code' on the next call
  241. // to search(*newAddr) if it is present.
  242. //
  243. void onewire_target_search(uint8_t pin, uint8_t family_code)
  244. {
  245. // set the search state to find SearchFamily type devices
  246. ROM_NO[pin][0] = family_code;
  247. uint8_t i;
  248. for (i = 1; i < 8; i++)
  249. ROM_NO[pin][i] = 0;
  250. LastDiscrepancy[pin] = 64;
  251. LastFamilyDiscrepancy[pin] = 0;
  252. LastDeviceFlag[pin] = FALSE;
  253. }
  254. //
  255. // Perform a search. If this function returns a '1' then it has
  256. // enumerated the next device and you may retrieve the ROM from the
  257. // OneWire::address variable. If there are no devices, no further
  258. // devices, or something horrible happens in the middle of the
  259. // enumeration then a 0 is returned. If a new device is found then
  260. // its address is copied to newAddr. Use OneWire::reset_search() to
  261. // start over.
  262. //
  263. // --- Replaced by the one from the Dallas Semiconductor web site ---
  264. //--------------------------------------------------------------------------
  265. // Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing
  266. // search state.
  267. // Return TRUE : device found, ROM number in ROM_NO buffer
  268. // FALSE : device not found, end of search
  269. //
  270. uint8_t onewire_search(uint8_t pin, uint8_t *newAddr, uint8_t alarm_search)
  271. {
  272. uint8_t id_bit_number;
  273. uint8_t last_zero, rom_byte_number, search_result;
  274. uint8_t id_bit, cmp_id_bit;
  275. unsigned char rom_byte_mask, search_direction;
  276. // initialize for search
  277. id_bit_number = 1;
  278. last_zero = 0;
  279. rom_byte_number = 0;
  280. rom_byte_mask = 1;
  281. search_result = 0;
  282. // if the last call was not the last one
  283. if (!LastDeviceFlag[pin])
  284. {
  285. // 1-Wire reset
  286. if (!onewire_reset(pin))
  287. {
  288. // reset the search
  289. LastDiscrepancy[pin] = 0;
  290. LastDeviceFlag[pin] = FALSE;
  291. LastFamilyDiscrepancy[pin] = 0;
  292. return FALSE;
  293. }
  294. // issue the search command
  295. onewire_write(pin, alarm_search ? 0xEC : 0xF0, owDefaultPower);
  296. // loop to do the search
  297. do
  298. {
  299. // read a bit and its complement
  300. id_bit = onewire_read_bit(pin);
  301. cmp_id_bit = onewire_read_bit(pin);
  302. // check for no devices on 1-wire
  303. if ((id_bit == 1) && (cmp_id_bit == 1))
  304. break;
  305. else
  306. {
  307. // all devices coupled have 0 or 1
  308. if (id_bit != cmp_id_bit)
  309. search_direction = id_bit; // bit write value for search
  310. else
  311. {
  312. // if this discrepancy if before the Last Discrepancy
  313. // on a previous next then pick the same as last time
  314. if (id_bit_number < LastDiscrepancy[pin])
  315. search_direction = ((ROM_NO[pin][rom_byte_number] & rom_byte_mask) > 0);
  316. else
  317. // if equal to last pick 1, if not then pick 0
  318. search_direction = (id_bit_number == LastDiscrepancy[pin]);
  319. // if 0 was picked then record its position in LastZero
  320. if (search_direction == 0)
  321. {
  322. last_zero = id_bit_number;
  323. // check for Last discrepancy in family
  324. if (last_zero < 9)
  325. LastFamilyDiscrepancy[pin] = last_zero;
  326. }
  327. }
  328. // set or clear the bit in the ROM byte rom_byte_number
  329. // with mask rom_byte_mask
  330. if (search_direction == 1)
  331. ROM_NO[pin][rom_byte_number] |= rom_byte_mask;
  332. else
  333. ROM_NO[pin][rom_byte_number] &= ~rom_byte_mask;
  334. // serial number search direction write bit
  335. onewire_write_bit(pin, search_direction, 0);
  336. // increment the byte counter id_bit_number
  337. // and shift the mask rom_byte_mask
  338. id_bit_number++;
  339. rom_byte_mask <<= 1;
  340. // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
  341. if (rom_byte_mask == 0)
  342. {
  343. rom_byte_number++;
  344. rom_byte_mask = 1;
  345. }
  346. }
  347. }
  348. while(rom_byte_number < 8); // loop until through all ROM bytes 0-7
  349. // if the search was successful then
  350. if (!(id_bit_number < 65))
  351. {
  352. // search successful so set LastDiscrepancy,LastDeviceFlag,search_result
  353. LastDiscrepancy[pin] = last_zero;
  354. // check for last device
  355. if (LastDiscrepancy[pin] == 0)
  356. LastDeviceFlag[pin] = TRUE;
  357. search_result = TRUE;
  358. }
  359. }
  360. // if no device found then reset counters so next 'search' will be like a first
  361. if (!search_result || !ROM_NO[pin][0])
  362. {
  363. LastDiscrepancy[pin] = 0;
  364. LastDeviceFlag[pin] = FALSE;
  365. LastFamilyDiscrepancy[pin] = 0;
  366. search_result = FALSE;
  367. }
  368. else
  369. {
  370. for (rom_byte_number = 0; rom_byte_number < 8; rom_byte_number++)
  371. {
  372. newAddr[rom_byte_number] = ROM_NO[pin][rom_byte_number];
  373. }
  374. }
  375. return search_result;
  376. }
  377. #endif
  378. #if ONEWIRE_CRC
  379. // The 1-Wire CRC scheme is described in Maxim Application Note 27:
  380. // "Understanding and Using Cyclic Redundancy Checks with Maxim iButton Products"
  381. //
  382. #if ONEWIRE_CRC8_TABLE
  383. // This table comes from Dallas sample code where it is freely reusable,
  384. // though Copyright (C) 2000 Dallas Semiconductor Corporation
  385. static const uint8_t dscrc_table[] = {
  386. 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
  387. 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
  388. 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
  389. 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
  390. 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
  391. 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
  392. 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
  393. 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
  394. 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
  395. 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
  396. 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
  397. 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
  398. 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
  399. 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
  400. 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
  401. 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};
  402. #ifndef pgm_read_byte
  403. #define pgm_read_byte(addr) (*(const uint8_t *)(addr))
  404. #endif
  405. //
  406. // Compute a Dallas Semiconductor 8 bit CRC. These show up in the ROM
  407. // and the registers. (note: this might better be done without to
  408. // table, it would probably be smaller and certainly fast enough
  409. // compared to all those delayMicrosecond() calls. But I got
  410. // confused, so I use this table from the examples.)
  411. //
  412. uint8_t onewire_crc8(const uint8_t *addr, uint8_t len)
  413. {
  414. uint8_t crc = 0;
  415. while (len--) {
  416. crc = pgm_read_byte(dscrc_table + (crc ^ *addr++));
  417. }
  418. return crc;
  419. }
  420. #else
  421. //
  422. // Compute a Dallas Semiconductor 8 bit CRC directly.
  423. // this is much slower, but much smaller, than the lookup table.
  424. //
  425. uint8_t onewire_crc8(const uint8_t *addr, uint8_t len)
  426. {
  427. uint8_t crc = 0;
  428. while (len--) {
  429. uint8_t inbyte = *addr++;
  430. uint8_t i;
  431. for (i = 8; i; i--) {
  432. uint8_t mix = (crc ^ inbyte) & 0x01;
  433. crc >>= 1;
  434. if (mix) crc ^= 0x8C;
  435. inbyte >>= 1;
  436. }
  437. }
  438. return crc;
  439. }
  440. #endif
  441. #if ONEWIRE_CRC16
  442. // Compute the 1-Wire CRC16 and compare it against the received CRC.
  443. // Example usage (reading a DS2408):
  444. // // Put everything in a buffer so we can compute the CRC easily.
  445. // uint8_t buf[13];
  446. // buf[0] = 0xF0; // Read PIO Registers
  447. // buf[1] = 0x88; // LSB address
  448. // buf[2] = 0x00; // MSB address
  449. // WriteBytes(net, buf, 3); // Write 3 cmd bytes
  450. // ReadBytes(net, buf+3, 10); // Read 6 data bytes, 2 0xFF, 2 CRC16
  451. // if (!CheckCRC16(buf, 11, &buf[11])) {
  452. // // Handle error.
  453. // }
  454. //
  455. // @param input - Array of bytes to checksum.
  456. // @param len - How many bytes to use.
  457. // @param inverted_crc - The two CRC16 bytes in the received data.
  458. // This should just point into the received data,
  459. // *not* at a 16-bit integer.
  460. // @param crc - The crc starting value (optional)
  461. // @return True, iff the CRC matches.
  462. bool onewire_check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc)
  463. {
  464. crc = ~onewire_crc16(input, len, crc);
  465. return (crc & 0xFF) == inverted_crc[0] && (crc >> 8) == inverted_crc[1];
  466. }
  467. // Compute a Dallas Semiconductor 16 bit CRC. This is required to check
  468. // the integrity of data received from many 1-Wire devices. Note that the
  469. // CRC computed here is *not* what you'll get from the 1-Wire network,
  470. // for two reasons:
  471. // 1) The CRC is transmitted bitwise inverted.
  472. // 2) Depending on the endian-ness of your processor, the binary
  473. // representation of the two-byte return value may have a different
  474. // byte order than the two bytes you get from 1-Wire.
  475. // @param input - Array of bytes to checksum.
  476. // @param len - How many bytes to use.
  477. // @param crc - The crc starting value (optional)
  478. // @return The CRC16, as defined by Dallas Semiconductor.
  479. uint16_t onewire_crc16(const uint8_t* input, uint16_t len, uint16_t crc)
  480. {
  481. static const uint8_t oddparity[16] =
  482. { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
  483. uint16_t i;
  484. for (i = 0 ; i < len ; i++) {
  485. // Even though we're just copying a byte from the input,
  486. // we'll be doing 16-bit computation with it.
  487. uint16_t cdata = input[i];
  488. cdata = (cdata ^ crc) & 0xff;
  489. crc >>= 8;
  490. if (oddparity[cdata & 0x0F] ^ oddparity[cdata >> 4])
  491. crc ^= 0xC001;
  492. cdata <<= 6;
  493. crc ^= cdata;
  494. cdata <<= 1;
  495. crc ^= cdata;
  496. }
  497. return crc;
  498. }
  499. #endif
  500. #endif