Library to communicate with Maxim OneWire protocol devices Modified timings and IRQ overrides
Fork of Onewire by
Onewire.cpp@8:5d0bd95b586f, 2015-10-16 (annotated)
- Committer:
- Bobty
- Date:
- Fri Oct 16 06:25:11 2015 +0000
- Revision:
- 8:5d0bd95b586f
- Parent:
- 7:0a87f8c2d9e6
Changed timings to be consistent with Arduino onewire library https://github.com/PaulStoffregen/OneWire
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 |
Bobty | 8:5d0bd95b586f | 20 | __disable_irq(); |
simonbarker | 0:d961f715d82b | 21 | oneBus_.output(); |
simonbarker | 0:d961f715d82b | 22 | oneBus_ = 0; |
Bobty | 8:5d0bd95b586f | 23 | wait_us(10); |
Bobty | 8:5d0bd95b586f | 24 | oneBus_ = 1; |
Bobty | 8:5d0bd95b586f | 25 | __enable_irq(); |
Bobty | 8:5d0bd95b586f | 26 | wait_us(55); |
Bobty | 2:b7ee49dbd7ef | 27 | } |
Bobty | 2:b7ee49dbd7ef | 28 | else |
Bobty | 2:b7ee49dbd7ef | 29 | { |
simonbarker | 0:d961f715d82b | 30 | // Write '0' bit |
Bobty | 8:5d0bd95b586f | 31 | __disable_irq(); |
simonbarker | 0:d961f715d82b | 32 | oneBus_.output(); |
simonbarker | 0:d961f715d82b | 33 | oneBus_ = 0; |
Bobty | 8:5d0bd95b586f | 34 | wait_us(65); |
Bobty | 8:5d0bd95b586f | 35 | oneBus_ = 1; |
Bobty | 8:5d0bd95b586f | 36 | __enable_irq(); |
Bobty | 8:5d0bd95b586f | 37 | wait_us(5); |
simonbarker | 0:d961f715d82b | 38 | } |
Bobty | 5:45b6a39002f1 | 39 | __enable_irq(); |
simonbarker | 0:d961f715d82b | 40 | } |
simonbarker | 0:d961f715d82b | 41 | |
Bobty | 2:b7ee49dbd7ef | 42 | int Onewire::readBit() |
Bobty | 2:b7ee49dbd7ef | 43 | { |
simonbarker | 0:d961f715d82b | 44 | char result; |
simonbarker | 0:d961f715d82b | 45 | |
Bobty | 5:45b6a39002f1 | 46 | __disable_irq(); |
simonbarker | 0:d961f715d82b | 47 | oneBus_.output(); |
simonbarker | 0:d961f715d82b | 48 | oneBus_ = 0; |
Bobty | 8:5d0bd95b586f | 49 | wait_us(3); |
simonbarker | 0:d961f715d82b | 50 | oneBus_.input(); |
Bobty | 8:5d0bd95b586f | 51 | wait_us(10); |
simonbarker | 0:d961f715d82b | 52 | result = oneBus_.read(); |
Bobty | 5:45b6a39002f1 | 53 | __enable_irq(); |
Bobty | 8:5d0bd95b586f | 54 | wait_us(53); |
simonbarker | 0:d961f715d82b | 55 | return result; |
simonbarker | 0:d961f715d82b | 56 | } |
simonbarker | 0:d961f715d82b | 57 | |
Bobty | 2:b7ee49dbd7ef | 58 | int Onewire::init() |
Bobty | 2:b7ee49dbd7ef | 59 | { |
Bobty | 8:5d0bd95b586f | 60 | // Ensure bus is high to start |
Bobty | 8:5d0bd95b586f | 61 | oneBus_.input(); |
Bobty | 8:5d0bd95b586f | 62 | int MAX_RETRY_TEST_BUS_HIGH = 125; |
Bobty | 8:5d0bd95b586f | 63 | for (int i = 0; i < MAX_RETRY_TEST_BUS_HIGH; i++) |
Bobty | 8:5d0bd95b586f | 64 | { |
Bobty | 8:5d0bd95b586f | 65 | if (oneBus_.read() == 1) |
Bobty | 8:5d0bd95b586f | 66 | break; |
Bobty | 8:5d0bd95b586f | 67 | wait_us(2); |
Bobty | 8:5d0bd95b586f | 68 | } |
Bobty | 8:5d0bd95b586f | 69 | if (oneBus_.read() != 1) |
Bobty | 8:5d0bd95b586f | 70 | return ONEWIRE_FAIL_STUCK_LOW; |
Bobty | 8:5d0bd95b586f | 71 | |
Bobty | 8:5d0bd95b586f | 72 | // Pull LOW for 480us |
Bobty | 8:5d0bd95b586f | 73 | __disable_irq(); |
simonbarker | 0:d961f715d82b | 74 | oneBus_.output(); |
simonbarker | 0:d961f715d82b | 75 | oneBus_ = 0; |
Bobty | 8:5d0bd95b586f | 76 | __enable_irq(); |
simonbarker | 0:d961f715d82b | 77 | wait_us(480); |
Bobty | 8:5d0bd95b586f | 78 | |
Bobty | 8:5d0bd95b586f | 79 | // Allow to float and test to ensure presence of devices |
Bobty | 8:5d0bd95b586f | 80 | // (which pull the bus low) |
Bobty | 5:45b6a39002f1 | 81 | __disable_irq(); |
simonbarker | 0:d961f715d82b | 82 | oneBus_.input(); |
Bobty | 8:5d0bd95b586f | 83 | wait_us(70); |
Bobty | 8:5d0bd95b586f | 84 | int readVal = oneBus_.read(); |
Bobty | 5:45b6a39002f1 | 85 | __enable_irq(); |
Bobty | 8:5d0bd95b586f | 86 | wait_us(410); |
Bobty | 8:5d0bd95b586f | 87 | return (readVal == 0) ? ONEWIRE_OK : ONEWIRE_SEARCH_INIT_FAIL; |
simonbarker | 0:d961f715d82b | 88 | } |
Bobty | 2:b7ee49dbd7ef | 89 | |
Bobty | 2:b7ee49dbd7ef | 90 | int Onewire::readByte() |
Bobty | 2:b7ee49dbd7ef | 91 | { |
simonbarker | 0:d961f715d82b | 92 | int result = 0; |
simonbarker | 0:d961f715d82b | 93 | |
Bobty | 4:b678c7c8203c | 94 | for (int loop = 0; loop < ONEWIRE_ADDR_BYTES; loop++) { |
simonbarker | 0:d961f715d82b | 95 | // shift the result to get it ready for the next bit |
simonbarker | 0:d961f715d82b | 96 | result >>= 1; |
simonbarker | 0:d961f715d82b | 97 | |
simonbarker | 0:d961f715d82b | 98 | // if result is one, then set MS bit |
simonbarker | 0:d961f715d82b | 99 | if (readBit()) |
simonbarker | 0:d961f715d82b | 100 | result |= 0x80; |
simonbarker | 0:d961f715d82b | 101 | } |
simonbarker | 0:d961f715d82b | 102 | return result; |
simonbarker | 0:d961f715d82b | 103 | } |
Bobty | 2:b7ee49dbd7ef | 104 | |
Bobty | 2:b7ee49dbd7ef | 105 | void Onewire::writeByte(char data) |
Bobty | 2:b7ee49dbd7ef | 106 | { |
simonbarker | 0:d961f715d82b | 107 | // Loop to write each bit in the byte, LS-bit first |
Bobty | 4:b678c7c8203c | 108 | for (int loop = 0; loop < ONEWIRE_ADDR_BYTES; loop++) { |
simonbarker | 0:d961f715d82b | 109 | writeBit(data & 0x01); |
simonbarker | 0:d961f715d82b | 110 | |
simonbarker | 0:d961f715d82b | 111 | // shift the data byte for the next bit |
simonbarker | 0:d961f715d82b | 112 | data >>= 1; |
simonbarker | 0:d961f715d82b | 113 | } |
simonbarker | 0:d961f715d82b | 114 | } |
Bobty | 2:b7ee49dbd7ef | 115 | |
Bobty | 2:b7ee49dbd7ef | 116 | unsigned char Onewire::CRC(unsigned char* addr, unsigned char len) |
Bobty | 2:b7ee49dbd7ef | 117 | { |
simonbarker | 0:d961f715d82b | 118 | unsigned char i, j; |
simonbarker | 0:d961f715d82b | 119 | unsigned char crc = 0; |
simonbarker | 0:d961f715d82b | 120 | |
simonbarker | 0:d961f715d82b | 121 | for (i = 0; i < len; i++) { |
simonbarker | 0:d961f715d82b | 122 | unsigned char inbyte = addr[i]; |
Bobty | 4:b678c7c8203c | 123 | for (j = 0; j < ONEWIRE_ADDR_BYTES; j++) { |
simonbarker | 0:d961f715d82b | 124 | unsigned char mix = (crc ^ inbyte) & 0x01; |
simonbarker | 0:d961f715d82b | 125 | crc >>= 1; |
simonbarker | 0:d961f715d82b | 126 | if (mix) crc ^= 0x8C; |
simonbarker | 0:d961f715d82b | 127 | inbyte >>= 1; |
simonbarker | 0:d961f715d82b | 128 | } |
simonbarker | 0:d961f715d82b | 129 | } |
simonbarker | 0:d961f715d82b | 130 | return crc; |
simonbarker | 0:d961f715d82b | 131 | } |
simonbarker | 0:d961f715d82b | 132 | |
Bobty | 1:8e9464e05ddf | 133 | // |
Bobty | 1:8e9464e05ddf | 134 | // You need to use this function to start a search again from the beginning. |
Bobty | 1:8e9464e05ddf | 135 | // You do not need to do it for the first search, though you could. |
Bobty | 1:8e9464e05ddf | 136 | // |
Bobty | 1:8e9464e05ddf | 137 | void Onewire::reset_search() |
Bobty | 1:8e9464e05ddf | 138 | { |
Bobty | 2:b7ee49dbd7ef | 139 | // reset the search state |
Bobty | 2:b7ee49dbd7ef | 140 | _search_LastDiscrepancy = 0; |
Bobty | 2:b7ee49dbd7ef | 141 | _search_LastDeviceFlag = false; |
Bobty | 2:b7ee49dbd7ef | 142 | _search_LastFamilyDiscrepancy = 0; |
Bobty | 4:b678c7c8203c | 143 | for(int i = ONEWIRE_ADDR_BYTES-1; i >= 0; i--) |
Bobty | 2:b7ee49dbd7ef | 144 | _search_ROM_NO[i] = 0; |
Bobty | 1:8e9464e05ddf | 145 | } |
Bobty | 1:8e9464e05ddf | 146 | |
Bobty | 7:0a87f8c2d9e6 | 147 | // Search Based on Maxim DS18B20 Algorithm |
Bobty | 7:0a87f8c2d9e6 | 148 | // https://www.maximintegrated.com/en/app-notes/index.mvp/id/187 |
Bobty | 1:8e9464e05ddf | 149 | // |
Bobty | 7:0a87f8c2d9e6 | 150 | // Perform a search, returns: |
Bobty | 6:d2452e9b169b | 151 | // ONEWIRE_OK if a new address has been returned. |
Bobty | 6:d2452e9b169b | 152 | // ONEWIRE_SEARCH_ALL_DONE = all devices found |
Bobty | 6:d2452e9b169b | 153 | // ONEWIRE_SEARCH_INIT_FAIL = failed to init |
Bobty | 6:d2452e9b169b | 154 | // ONEWIRE_SEARCH_NOT_FOUND = no devices found If this function returns a '1' then it has |
Bobty | 7:0a87f8c2d9e6 | 155 | // ONEWIRE_SEARCH_STUCK_HIGH = bus is stuck high |
Bobty | 7:0a87f8c2d9e6 | 156 | // ONEWIRE_SEARCH_COMP_BIT_ERR = complement bit error |
Bobty | 1:8e9464e05ddf | 157 | // |
Bobty | 1:8e9464e05ddf | 158 | uint8_t Onewire::search(uint8_t *newAddr) |
Bobty | 1:8e9464e05ddf | 159 | { |
Bobty | 7:0a87f8c2d9e6 | 160 | // initialize for search |
Bobty | 7:0a87f8c2d9e6 | 161 | uint8_t last_zero = 0; |
Bobty | 7:0a87f8c2d9e6 | 162 | unsigned char search_direction = 0; |
Bobty | 1:8e9464e05ddf | 163 | |
Bobty | 7:0a87f8c2d9e6 | 164 | // if the previous call was the last one |
Bobty | 7:0a87f8c2d9e6 | 165 | if (_search_LastDeviceFlag) |
Bobty | 7:0a87f8c2d9e6 | 166 | return ONEWIRE_SEARCH_ALL_DONE; |
Bobty | 7:0a87f8c2d9e6 | 167 | |
Bobty | 7:0a87f8c2d9e6 | 168 | // 1-Wire reset |
Bobty | 7:0a87f8c2d9e6 | 169 | int initRslt = init(); |
Bobty | 7:0a87f8c2d9e6 | 170 | if (initRslt != ONEWIRE_OK) |
Bobty | 7:0a87f8c2d9e6 | 171 | { |
Bobty | 7:0a87f8c2d9e6 | 172 | // reset the search |
Bobty | 7:0a87f8c2d9e6 | 173 | reset_search(); |
Bobty | 7:0a87f8c2d9e6 | 174 | return initRslt; |
Bobty | 7:0a87f8c2d9e6 | 175 | } |
Bobty | 7:0a87f8c2d9e6 | 176 | |
Bobty | 7:0a87f8c2d9e6 | 177 | // issue the search command |
Bobty | 7:0a87f8c2d9e6 | 178 | writeByte(0xF0); |
Bobty | 7:0a87f8c2d9e6 | 179 | |
Bobty | 7:0a87f8c2d9e6 | 180 | // loop to do the search |
Bobty | 7:0a87f8c2d9e6 | 181 | for (int id_bit_number = 1; id_bit_number <= 64; id_bit_number++) |
Bobty | 7:0a87f8c2d9e6 | 182 | { |
Bobty | 7:0a87f8c2d9e6 | 183 | // read a bit and its complement |
Bobty | 7:0a87f8c2d9e6 | 184 | uint8_t id_bit = readBit(); |
Bobty | 7:0a87f8c2d9e6 | 185 | uint8_t cmp_id_bit = readBit(); |
Bobty | 7:0a87f8c2d9e6 | 186 | |
Bobty | 7:0a87f8c2d9e6 | 187 | // check for no devices on 1-wire |
Bobty | 7:0a87f8c2d9e6 | 188 | if ((id_bit == 1) && (cmp_id_bit == 1)) |
Bobty | 7:0a87f8c2d9e6 | 189 | { |
Bobty | 7:0a87f8c2d9e6 | 190 | reset_search(); |
Bobty | 7:0a87f8c2d9e6 | 191 | return ONEWIRE_SEARCH_COMP_BIT_ERR; |
Bobty | 7:0a87f8c2d9e6 | 192 | } |
Bobty | 1:8e9464e05ddf | 193 | |
Bobty | 7:0a87f8c2d9e6 | 194 | // all devices coupled have 0 or 1 |
Bobty | 7:0a87f8c2d9e6 | 195 | int byteNo = (id_bit_number - 1) / 8; |
Bobty | 7:0a87f8c2d9e6 | 196 | int byteMask = 1 << ((id_bit_number - 1) % 8); |
Bobty | 7:0a87f8c2d9e6 | 197 | if (id_bit != cmp_id_bit) |
Bobty | 7:0a87f8c2d9e6 | 198 | { |
Bobty | 7:0a87f8c2d9e6 | 199 | search_direction = id_bit; // bit write value for search |
Bobty | 7:0a87f8c2d9e6 | 200 | } |
Bobty | 7:0a87f8c2d9e6 | 201 | else |
Bobty | 7:0a87f8c2d9e6 | 202 | { |
Bobty | 7:0a87f8c2d9e6 | 203 | if (id_bit_number == _search_LastDiscrepancy) |
Bobty | 7:0a87f8c2d9e6 | 204 | { |
Bobty | 7:0a87f8c2d9e6 | 205 | search_direction = 1; |
Bobty | 7:0a87f8c2d9e6 | 206 | } |
Bobty | 7:0a87f8c2d9e6 | 207 | else if (id_bit_number > _search_LastDiscrepancy) |
Bobty | 7:0a87f8c2d9e6 | 208 | { |
Bobty | 7:0a87f8c2d9e6 | 209 | search_direction = 0; |
Bobty | 7:0a87f8c2d9e6 | 210 | } |
Bobty | 1:8e9464e05ddf | 211 | else |
Bobty | 1:8e9464e05ddf | 212 | { |
Bobty | 7:0a87f8c2d9e6 | 213 | search_direction = ((_search_ROM_NO[byteNo] & byteMask) > 0); |
Bobty | 1:8e9464e05ddf | 214 | } |
Bobty | 7:0a87f8c2d9e6 | 215 | |
Bobty | 7:0a87f8c2d9e6 | 216 | // if 0 was picked then record its position in LastZero |
Bobty | 7:0a87f8c2d9e6 | 217 | if (search_direction == 0) |
Bobty | 1:8e9464e05ddf | 218 | { |
Bobty | 7:0a87f8c2d9e6 | 219 | last_zero = id_bit_number; |
Bobty | 7:0a87f8c2d9e6 | 220 | // check for Last discrepancy in family |
Bobty | 7:0a87f8c2d9e6 | 221 | if (last_zero < 9) |
Bobty | 7:0a87f8c2d9e6 | 222 | _search_LastFamilyDiscrepancy = last_zero; |
Bobty | 1:8e9464e05ddf | 223 | } |
Bobty | 7:0a87f8c2d9e6 | 224 | } |
Bobty | 7:0a87f8c2d9e6 | 225 | |
Bobty | 7:0a87f8c2d9e6 | 226 | // set or clear the bit in the ROM byte rom_byte_number |
Bobty | 7:0a87f8c2d9e6 | 227 | // with mask rom_byte_mask |
Bobty | 7:0a87f8c2d9e6 | 228 | |
Bobty | 7:0a87f8c2d9e6 | 229 | if (search_direction == 1) |
Bobty | 7:0a87f8c2d9e6 | 230 | _search_ROM_NO[byteNo] |= byteMask; |
Bobty | 7:0a87f8c2d9e6 | 231 | else |
Bobty | 7:0a87f8c2d9e6 | 232 | _search_ROM_NO[byteNo] &= ~byteMask; |
Bobty | 7:0a87f8c2d9e6 | 233 | |
Bobty | 7:0a87f8c2d9e6 | 234 | // serial number search direction write bit |
Bobty | 7:0a87f8c2d9e6 | 235 | writeBit(search_direction); |
Bobty | 7:0a87f8c2d9e6 | 236 | } |
Bobty | 7:0a87f8c2d9e6 | 237 | |
Bobty | 7:0a87f8c2d9e6 | 238 | // search successful so set LastDiscrepancy,LastDeviceFlag,search_result |
Bobty | 7:0a87f8c2d9e6 | 239 | _search_LastDiscrepancy = last_zero; |
Bobty | 7:0a87f8c2d9e6 | 240 | // check for last device |
Bobty | 7:0a87f8c2d9e6 | 241 | if (_search_LastDiscrepancy == 0) |
Bobty | 7:0a87f8c2d9e6 | 242 | _search_LastDeviceFlag = true; |
Bobty | 7:0a87f8c2d9e6 | 243 | |
Bobty | 7:0a87f8c2d9e6 | 244 | // Copy address to return |
Bobty | 7:0a87f8c2d9e6 | 245 | for (int i = 0; i < ONEWIRE_ADDR_BYTES; i++) |
Bobty | 7:0a87f8c2d9e6 | 246 | newAddr[i] = _search_ROM_NO[i]; |
Bobty | 7:0a87f8c2d9e6 | 247 | |
Bobty | 7:0a87f8c2d9e6 | 248 | return ONEWIRE_OK; |
Bobty | 7:0a87f8c2d9e6 | 249 | } |
Bobty | 1:8e9464e05ddf | 250 | |
Bobty | 7:0a87f8c2d9e6 | 251 | char* Onewire::GetErrorStr(int errCode) |
Bobty | 7:0a87f8c2d9e6 | 252 | { |
Bobty | 7:0a87f8c2d9e6 | 253 | switch(errCode) |
Bobty | 7:0a87f8c2d9e6 | 254 | { |
Bobty | 7:0a87f8c2d9e6 | 255 | case ONEWIRE_OK: return "OK"; |
Bobty | 8:5d0bd95b586f | 256 | case ONEWIRE_FAIL_STUCK_LOW: return "Stuck Low"; |
Bobty | 7:0a87f8c2d9e6 | 257 | case ONEWIRE_SEARCH_ALL_DONE: return "All Done"; |
Bobty | 7:0a87f8c2d9e6 | 258 | case ONEWIRE_SEARCH_INIT_FAIL: return "Init Fail"; |
Bobty | 7:0a87f8c2d9e6 | 259 | case ONEWIRE_SEARCH_NOT_FOUND: return "Not Found"; |
Bobty | 7:0a87f8c2d9e6 | 260 | case ONEWIRE_SEARCH_COMP_BIT_ERR: return "Comp Bit Err"; |
Bobty | 7:0a87f8c2d9e6 | 261 | } |
Bobty | 7:0a87f8c2d9e6 | 262 | return "Unknown Err"; |
Bobty | 7:0a87f8c2d9e6 | 263 | } |
Bobty | 7:0a87f8c2d9e6 | 264 |