oneWire.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. #include "stm32f1xx_hal.h"
  2. #include "oneWireDriver.h"
  3. #include<stdio.h>
  4. #include<stdbool.h>
  5. // global search state
  6. static unsigned char ROM_NO[8];
  7. static uint8_t LastDiscrepancy;
  8. static uint8_t LastFamilyDiscrepancy;
  9. static bool LastDeviceFlag;
  10. void reset_oneWireSearch()
  11. {
  12. // reset the search state
  13. LastDiscrepancy = 0;
  14. LastDeviceFlag = false;
  15. LastFamilyDiscrepancy = 0;
  16. for(int i = 7; ; i--) {
  17. ROM_NO[i] = 0;
  18. if ( i == 0) break;
  19. }
  20. }
  21. bool oneWireSearch(uint64_t *newAddr )
  22. {
  23. const bool search_mode = true;
  24. uint8_t id_bit_number;
  25. uint8_t last_zero, rom_byte_number;
  26. bool search_result;
  27. uint8_t id_bit, cmp_id_bit;
  28. unsigned char rom_byte_mask, search_direction;
  29. // initialize for search
  30. id_bit_number = 1;
  31. last_zero = 0;
  32. rom_byte_number = 0;
  33. rom_byte_mask = 1;
  34. search_result = false;
  35. // if the last call was not the last one
  36. if (!LastDeviceFlag) {
  37. // 1-Wire reset
  38. if (!oneWire_init()) {
  39. // reset the search
  40. LastDiscrepancy = 0;
  41. LastDeviceFlag = false;
  42. LastFamilyDiscrepancy = 0;
  43. return false;
  44. }
  45. // issue the search command
  46. if (search_mode == true) {
  47. writeByte(0xF0); // NORMAL SEARCH
  48. } else {
  49. writeByte(0xEC); // CONDITIONAL SEARCH
  50. }
  51. // loop to do the search
  52. do
  53. {
  54. // read a bit and its complement
  55. id_bit = readSlot();
  56. cmp_id_bit = readSlot();
  57. // check for no devices on 1-wire
  58. if ((id_bit == 1) && (cmp_id_bit == 1)) {
  59. break;
  60. } else {
  61. // all devices coupled have 0 or 1
  62. if (id_bit != cmp_id_bit) {
  63. search_direction = id_bit; // bit write value for search
  64. } else {
  65. // if this discrepancy if before the Last Discrepancy
  66. // on a previous next then pick the same as last time
  67. if (id_bit_number < LastDiscrepancy) {
  68. search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0);
  69. } else {
  70. // if equal to last pick 1, if not then pick 0
  71. search_direction = (id_bit_number == LastDiscrepancy);
  72. }
  73. // if 0 was picked then record its position in LastZero
  74. if (search_direction == 0) {
  75. last_zero = id_bit_number;
  76. // check for Last discrepancy in family
  77. if (last_zero < 9)
  78. LastFamilyDiscrepancy = last_zero;
  79. }
  80. }
  81. // set or clear the bit in the ROM byte rom_byte_number
  82. // with mask rom_byte_mask
  83. if (search_direction == 1)
  84. ROM_NO[rom_byte_number] |= rom_byte_mask;
  85. else
  86. ROM_NO[rom_byte_number] &= ~rom_byte_mask;
  87. // serial number search direction write bit
  88. writeSlot(search_direction);
  89. // increment the byte counter id_bit_number
  90. // and shift the mask rom_byte_mask
  91. id_bit_number++;
  92. rom_byte_mask <<= 1;
  93. // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
  94. if (rom_byte_mask == 0) {
  95. rom_byte_number++;
  96. rom_byte_mask = 1;
  97. }
  98. }
  99. }
  100. while(rom_byte_number < 8); // loop until through all ROM bytes 0-7
  101. // if the search was successful then
  102. if (!(id_bit_number < 65)) {
  103. // search successful so set LastDiscrepancy,LastDeviceFlag,search_result
  104. LastDiscrepancy = last_zero;
  105. // check for last device
  106. if (LastDiscrepancy == 0) {
  107. LastDeviceFlag = true;
  108. }
  109. search_result = true;
  110. }
  111. }
  112. // if no device found then reset counters so next 'search' will be like a first
  113. if (!search_result || !ROM_NO[0]) {
  114. LastDiscrepancy = 0;
  115. LastDeviceFlag = false;
  116. LastFamilyDiscrepancy = 0;
  117. search_result = false;
  118. } else {
  119. for (int i = 0; i < 8; i++) {
  120. (*newAddr)<<=8;
  121. (*newAddr) |= ROM_NO[i];
  122. }
  123. }
  124. return search_result;
  125. }
  126. static void sendROMCode(const uint64_t adr) {
  127. for( uint8_t i = 8; i>0; i--) writeByte( (uint8_t)(adr >> ((i-1)*8))&0xFF );
  128. }
  129. void setConfigRegister(const uint64_t adr, const uint8_t value) {
  130. oneWire_init();
  131. writeByte(0x55); // match ROM
  132. sendROMCode(adr);
  133. writeByte(0x55); // Write Scratchpad (3 bytes)
  134. writeByte(0x00);
  135. writeByte(0x00);
  136. writeByte( (((value)|0x1F)&0x7F) );
  137. }
  138. static uint32_t initReadTemp(const uint64_t adr)
  139. {
  140. uint32_t noOfSlots = 0;
  141. oneWire_init();
  142. writeByte(0x55); // match ROM
  143. sendROMCode(adr);
  144. writeByte(0x44); // convert t
  145. while( readSlot() == 0 ) {
  146. noOfSlots++;
  147. us_delay(1000);
  148. if( noOfSlots > 800 ) break; // Cancel after 800mS
  149. }
  150. return noOfSlots;
  151. }
  152. float readTemperature(const uint64_t adr)
  153. {
  154. initReadTemp(adr);
  155. oneWire_init();
  156. writeByte(0x55); // skip ROM
  157. sendROMCode(adr);
  158. writeByte(0xBE); // Read Scratchpad
  159. uint8_t b0 = readByte();
  160. uint8_t b1 = readByte();
  161. //uint8_t b2 = readByte();
  162. //uint8_t b3 = readByte();
  163. uint8_t b4 = readByte();
  164. //uint8_t b5 = readByte();
  165. //uint8_t b6 = readByte();
  166. //uint8_t b7 = readByte();
  167. uint16_t raw = (int16_t)((b1 << 8) | b0);
  168. uint16_t cfg = (b4 & 0x60);
  169. // at lower res, the low bits are undefined, so let's zero them
  170. if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
  171. else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
  172. else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
  173. //// default is 12 bit resolution, 750 ms conversion time
  174. float temperature = (float)raw / 16.0;
  175. //printf("%lumS : %02X %02X %02X %02X %02X",time_ms,b0,b1,b2,b3,b4);
  176. //printf(" %02X %02X %02X = %.02f\n",b5,b6,b7,temperature);
  177. return temperature;
  178. }