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