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

Dependents:   RdGasUseMonitor

Fork of Onewire by Simon Barker

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?

UserRevisionLine numberNew 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