Library to communicate with Maxim OneWire protocol devices Modified timings and IRQ overrides

Dependents:   RdGasUseMonitor

Fork of Onewire by Simon Barker

Committer:
Bobty
Date:
Sat Feb 21 17:16:16 2015 +0000
Revision:
1:8e9464e05ddf
Parent:
0:d961f715d82b
Child:
2:b7ee49dbd7ef
Added search function to find existing addresses

Who changed what in which revision?

UserRevisionLine numberNew contents of line
simonbarker 0:d961f715d82b 1 #include "Onewire.h"
simonbarker 0:d961f715d82b 2
simonbarker 0:d961f715d82b 3 Onewire::Onewire(PinName oneBus):oneBus_(oneBus){
simonbarker 0:d961f715d82b 4
simonbarker 0:d961f715d82b 5 }
simonbarker 0:d961f715d82b 6 void Onewire::writeBit(int bit) {
simonbarker 0:d961f715d82b 7 bit = bit & 0x01;
simonbarker 0:d961f715d82b 8 if (bit) {
simonbarker 0:d961f715d82b 9 // Write '1' bit
simonbarker 0:d961f715d82b 10 oneBus_.output();
simonbarker 0:d961f715d82b 11 oneBus_ = 0;
simonbarker 0:d961f715d82b 12 wait_us(5);
simonbarker 0:d961f715d82b 13 oneBus_.input();
simonbarker 0:d961f715d82b 14 wait_us(60);
simonbarker 0:d961f715d82b 15 } else {
simonbarker 0:d961f715d82b 16 // Write '0' bit
simonbarker 0:d961f715d82b 17 oneBus_.output();
simonbarker 0:d961f715d82b 18 oneBus_ = 0;
simonbarker 0:d961f715d82b 19 wait_us(70);
simonbarker 0:d961f715d82b 20 oneBus_.input();
simonbarker 0:d961f715d82b 21 wait_us(2);
simonbarker 0:d961f715d82b 22 }
simonbarker 0:d961f715d82b 23 }
simonbarker 0:d961f715d82b 24
simonbarker 0:d961f715d82b 25 int Onewire::readBit() {
simonbarker 0:d961f715d82b 26 char result;
simonbarker 0:d961f715d82b 27
simonbarker 0:d961f715d82b 28 oneBus_.output();
simonbarker 0:d961f715d82b 29 oneBus_ = 0;
simonbarker 0:d961f715d82b 30 wait_us(1);
simonbarker 0:d961f715d82b 31 oneBus_.input();
simonbarker 0:d961f715d82b 32 wait_us(5);
simonbarker 0:d961f715d82b 33 result = oneBus_.read();
simonbarker 0:d961f715d82b 34 wait_us(55);
simonbarker 0:d961f715d82b 35 return result;
simonbarker 0:d961f715d82b 36
simonbarker 0:d961f715d82b 37 }
simonbarker 0:d961f715d82b 38
simonbarker 0:d961f715d82b 39 int Onewire::init() {
simonbarker 0:d961f715d82b 40 oneBus_.output();
simonbarker 0:d961f715d82b 41 oneBus_ = 0;
simonbarker 0:d961f715d82b 42 wait_us(480);
simonbarker 0:d961f715d82b 43 oneBus_.input();
simonbarker 0:d961f715d82b 44 wait_us(60);
simonbarker 0:d961f715d82b 45 if (oneBus_.read() == 0) {
simonbarker 0:d961f715d82b 46 wait(0.0001);
simonbarker 0:d961f715d82b 47 return 1;
simonbarker 0:d961f715d82b 48 }
simonbarker 0:d961f715d82b 49 return 0;
simonbarker 0:d961f715d82b 50 }
simonbarker 0:d961f715d82b 51 int Onewire::readByte() {
simonbarker 0:d961f715d82b 52 int result = 0;
simonbarker 0:d961f715d82b 53
simonbarker 0:d961f715d82b 54 for (int loop = 0; loop < 8; loop++) {
simonbarker 0:d961f715d82b 55 // shift the result to get it ready for the next bit
simonbarker 0:d961f715d82b 56 result >>= 1;
simonbarker 0:d961f715d82b 57
simonbarker 0:d961f715d82b 58 // if result is one, then set MS bit
simonbarker 0:d961f715d82b 59 if (readBit())
simonbarker 0:d961f715d82b 60 result |= 0x80;
simonbarker 0:d961f715d82b 61 }
simonbarker 0:d961f715d82b 62 return result;
simonbarker 0:d961f715d82b 63 }
simonbarker 0:d961f715d82b 64 void Onewire::writeByte(char data) {
simonbarker 0:d961f715d82b 65 // Loop to write each bit in the byte, LS-bit first
simonbarker 0:d961f715d82b 66 for (int loop = 0; loop < 8; loop++) {
simonbarker 0:d961f715d82b 67 writeBit(data & 0x01);
simonbarker 0:d961f715d82b 68
simonbarker 0:d961f715d82b 69 // shift the data byte for the next bit
simonbarker 0:d961f715d82b 70 data >>= 1;
simonbarker 0:d961f715d82b 71 }
simonbarker 0:d961f715d82b 72 }
simonbarker 0:d961f715d82b 73 unsigned char Onewire::CRC(unsigned char* addr, unsigned char len) {
simonbarker 0:d961f715d82b 74 unsigned char i, j;
simonbarker 0:d961f715d82b 75 unsigned char crc = 0;
simonbarker 0:d961f715d82b 76
simonbarker 0:d961f715d82b 77 for (i = 0; i < len; i++) {
simonbarker 0:d961f715d82b 78 unsigned char inbyte = addr[i];
simonbarker 0:d961f715d82b 79 for (j = 0; j < 8; j++) {
simonbarker 0:d961f715d82b 80 unsigned char mix = (crc ^ inbyte) & 0x01;
simonbarker 0:d961f715d82b 81 crc >>= 1;
simonbarker 0:d961f715d82b 82 if (mix) crc ^= 0x8C;
simonbarker 0:d961f715d82b 83 inbyte >>= 1;
simonbarker 0:d961f715d82b 84 }
simonbarker 0:d961f715d82b 85 }
simonbarker 0:d961f715d82b 86
simonbarker 0:d961f715d82b 87 return crc;
simonbarker 0:d961f715d82b 88 }
simonbarker 0:d961f715d82b 89
Bobty 1:8e9464e05ddf 90 //
Bobty 1:8e9464e05ddf 91 // You need to use this function to start a search again from the beginning.
Bobty 1:8e9464e05ddf 92 // You do not need to do it for the first search, though you could.
Bobty 1:8e9464e05ddf 93 //
Bobty 1:8e9464e05ddf 94 void Onewire::reset_search()
Bobty 1:8e9464e05ddf 95 {
Bobty 1:8e9464e05ddf 96 // reset the search state
Bobty 1:8e9464e05ddf 97 _search_LastDiscrepancy = 0;
Bobty 1:8e9464e05ddf 98 _search_LastDeviceFlag = false;
Bobty 1:8e9464e05ddf 99 _search_LastFamilyDiscrepancy = 0;
Bobty 1:8e9464e05ddf 100 for(int i = 7; ; i--) {
Bobty 1:8e9464e05ddf 101 _search_ROM_NO[i] = 0;
Bobty 1:8e9464e05ddf 102 if ( i == 0) break;
Bobty 1:8e9464e05ddf 103 }
Bobty 1:8e9464e05ddf 104 }
Bobty 1:8e9464e05ddf 105
Bobty 1:8e9464e05ddf 106 //
Bobty 1:8e9464e05ddf 107 // Perform a search. If this function returns a '1' then it has
Bobty 1:8e9464e05ddf 108 // enumerated the next device and you may retrieve the ROM from the
Bobty 1:8e9464e05ddf 109 // Onewire::address variable. If there are no devices, no further
Bobty 1:8e9464e05ddf 110 // devices, or something horrible happens in the middle of the
Bobty 1:8e9464e05ddf 111 // enumeration then a 0 is returned. If a new device is found then
Bobty 1:8e9464e05ddf 112 // its address is copied to newAddr. Use Onewire::reset_search() to
Bobty 1:8e9464e05ddf 113 // start over.
Bobty 1:8e9464e05ddf 114 //
Bobty 1:8e9464e05ddf 115 // --- Replaced by the one from the Dallas Semiconductor web site ---
Bobty 1:8e9464e05ddf 116 //--------------------------------------------------------------------------
Bobty 1:8e9464e05ddf 117 // Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing
Bobty 1:8e9464e05ddf 118 // search state.
Bobty 1:8e9464e05ddf 119 // Return TRUE : device found, ROM number in ROM_NO buffer
Bobty 1:8e9464e05ddf 120 // FALSE : device not found, end of search
Bobty 1:8e9464e05ddf 121 //
Bobty 1:8e9464e05ddf 122 uint8_t Onewire::search(uint8_t *newAddr)
Bobty 1:8e9464e05ddf 123 {
Bobty 1:8e9464e05ddf 124 uint8_t id_bit_number;
Bobty 1:8e9464e05ddf 125 uint8_t last_zero, rom_byte_number, search_result;
Bobty 1:8e9464e05ddf 126 uint8_t id_bit, cmp_id_bit;
Bobty 1:8e9464e05ddf 127
Bobty 1:8e9464e05ddf 128 unsigned char rom_byte_mask, search_direction;
Bobty 1:8e9464e05ddf 129
Bobty 1:8e9464e05ddf 130 // initialize for search
Bobty 1:8e9464e05ddf 131 id_bit_number = 1;
Bobty 1:8e9464e05ddf 132 last_zero = 0;
Bobty 1:8e9464e05ddf 133 rom_byte_number = 0;
Bobty 1:8e9464e05ddf 134 rom_byte_mask = 1;
Bobty 1:8e9464e05ddf 135 search_result = 0;
Bobty 1:8e9464e05ddf 136
Bobty 1:8e9464e05ddf 137 // if the last call was not the last one
Bobty 1:8e9464e05ddf 138 if (!_search_LastDeviceFlag)
Bobty 1:8e9464e05ddf 139 {
Bobty 1:8e9464e05ddf 140 // 1-Wire reset
Bobty 1:8e9464e05ddf 141 if (!init())
Bobty 1:8e9464e05ddf 142 {
Bobty 1:8e9464e05ddf 143 // reset the search
Bobty 1:8e9464e05ddf 144 _search_LastDiscrepancy = 0;
Bobty 1:8e9464e05ddf 145 _search_LastDeviceFlag = false;
Bobty 1:8e9464e05ddf 146 _search_LastFamilyDiscrepancy = 0;
Bobty 1:8e9464e05ddf 147 return false;
Bobty 1:8e9464e05ddf 148 }
Bobty 1:8e9464e05ddf 149
Bobty 1:8e9464e05ddf 150 // issue the search command
Bobty 1:8e9464e05ddf 151 writeByte(0xF0);
Bobty 1:8e9464e05ddf 152
Bobty 1:8e9464e05ddf 153 // loop to do the search
Bobty 1:8e9464e05ddf 154 do
Bobty 1:8e9464e05ddf 155 {
Bobty 1:8e9464e05ddf 156 // read a bit and its complement
Bobty 1:8e9464e05ddf 157 id_bit = readBit();
Bobty 1:8e9464e05ddf 158 cmp_id_bit = readBit();
Bobty 1:8e9464e05ddf 159
Bobty 1:8e9464e05ddf 160 // check for no devices on 1-wire
Bobty 1:8e9464e05ddf 161 if ((id_bit == 1) && (cmp_id_bit == 1))
Bobty 1:8e9464e05ddf 162 break;
Bobty 1:8e9464e05ddf 163 else
Bobty 1:8e9464e05ddf 164 {
Bobty 1:8e9464e05ddf 165 // all devices coupled have 0 or 1
Bobty 1:8e9464e05ddf 166 if (id_bit != cmp_id_bit)
Bobty 1:8e9464e05ddf 167 search_direction = id_bit; // bit write value for search
Bobty 1:8e9464e05ddf 168 else
Bobty 1:8e9464e05ddf 169 {
Bobty 1:8e9464e05ddf 170 // if this discrepancy if before the Last Discrepancy
Bobty 1:8e9464e05ddf 171 // on a previous next then pick the same as last time
Bobty 1:8e9464e05ddf 172 if (id_bit_number < _search_LastDiscrepancy)
Bobty 1:8e9464e05ddf 173 search_direction = ((_search_ROM_NO[rom_byte_number] & rom_byte_mask) > 0);
Bobty 1:8e9464e05ddf 174 else
Bobty 1:8e9464e05ddf 175 // if equal to last pick 1, if not then pick 0
Bobty 1:8e9464e05ddf 176 search_direction = (id_bit_number == _search_LastDiscrepancy);
Bobty 1:8e9464e05ddf 177
Bobty 1:8e9464e05ddf 178 // if 0 was picked then record its position in LastZero
Bobty 1:8e9464e05ddf 179 if (search_direction == 0)
Bobty 1:8e9464e05ddf 180 {
Bobty 1:8e9464e05ddf 181 last_zero = id_bit_number;
Bobty 1:8e9464e05ddf 182
Bobty 1:8e9464e05ddf 183 // check for Last discrepancy in family
Bobty 1:8e9464e05ddf 184 if (last_zero < 9)
Bobty 1:8e9464e05ddf 185 _search_LastFamilyDiscrepancy = last_zero;
Bobty 1:8e9464e05ddf 186 }
Bobty 1:8e9464e05ddf 187 }
Bobty 1:8e9464e05ddf 188
Bobty 1:8e9464e05ddf 189 // set or clear the bit in the ROM byte rom_byte_number
Bobty 1:8e9464e05ddf 190 // with mask rom_byte_mask
Bobty 1:8e9464e05ddf 191 if (search_direction == 1)
Bobty 1:8e9464e05ddf 192 _search_ROM_NO[rom_byte_number] |= rom_byte_mask;
Bobty 1:8e9464e05ddf 193 else
Bobty 1:8e9464e05ddf 194 _search_ROM_NO[rom_byte_number] &= ~rom_byte_mask;
Bobty 1:8e9464e05ddf 195
Bobty 1:8e9464e05ddf 196 // serial number search direction write bit
Bobty 1:8e9464e05ddf 197 writeBit(search_direction);
Bobty 1:8e9464e05ddf 198
Bobty 1:8e9464e05ddf 199 // increment the byte counter id_bit_number
Bobty 1:8e9464e05ddf 200 // and shift the mask rom_byte_mask
Bobty 1:8e9464e05ddf 201 id_bit_number++;
Bobty 1:8e9464e05ddf 202 rom_byte_mask <<= 1;
Bobty 1:8e9464e05ddf 203
Bobty 1:8e9464e05ddf 204 // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
Bobty 1:8e9464e05ddf 205 if (rom_byte_mask == 0)
Bobty 1:8e9464e05ddf 206 {
Bobty 1:8e9464e05ddf 207 rom_byte_number++;
Bobty 1:8e9464e05ddf 208 rom_byte_mask = 1;
Bobty 1:8e9464e05ddf 209 }
Bobty 1:8e9464e05ddf 210 }
Bobty 1:8e9464e05ddf 211 }
Bobty 1:8e9464e05ddf 212 while(rom_byte_number < 8); // loop until through all ROM bytes 0-7
Bobty 1:8e9464e05ddf 213
Bobty 1:8e9464e05ddf 214 // if the search was successful then
Bobty 1:8e9464e05ddf 215 if (!(id_bit_number < 65))
Bobty 1:8e9464e05ddf 216 {
Bobty 1:8e9464e05ddf 217 // search successful so set LastDiscrepancy,LastDeviceFlag,search_result
Bobty 1:8e9464e05ddf 218 _search_LastDiscrepancy = last_zero;
Bobty 1:8e9464e05ddf 219
Bobty 1:8e9464e05ddf 220 // check for last device
Bobty 1:8e9464e05ddf 221 if (_search_LastDiscrepancy == 0)
Bobty 1:8e9464e05ddf 222 _search_LastDeviceFlag = true;
Bobty 1:8e9464e05ddf 223
Bobty 1:8e9464e05ddf 224 search_result = true;
Bobty 1:8e9464e05ddf 225 }
Bobty 1:8e9464e05ddf 226 }
Bobty 1:8e9464e05ddf 227
Bobty 1:8e9464e05ddf 228 // if no device found then reset counters so next 'search' will be like a first
Bobty 1:8e9464e05ddf 229 if (!search_result || !_search_ROM_NO[0])
Bobty 1:8e9464e05ddf 230 {
Bobty 1:8e9464e05ddf 231 _search_LastDiscrepancy = 0;
Bobty 1:8e9464e05ddf 232 _search_LastDeviceFlag = false;
Bobty 1:8e9464e05ddf 233 _search_LastFamilyDiscrepancy = 0;
Bobty 1:8e9464e05ddf 234 search_result = false;
Bobty 1:8e9464e05ddf 235 }
Bobty 1:8e9464e05ddf 236 for (int i = 0; i < 8; i++)
Bobty 1:8e9464e05ddf 237 newAddr[i] = _search_ROM_NO[i];
Bobty 1:8e9464e05ddf 238 return search_result;
Bobty 1:8e9464e05ddf 239 }
Bobty 1:8e9464e05ddf 240