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

Dependents:   RdGasUseMonitor

Fork of Onewire by Simon Barker

Committer:
Bobty
Date:
Thu Oct 15 21:39:21 2015 +0000
Revision:
7:0a87f8c2d9e6
Parent:
6:d2452e9b169b
Child:
8:5d0bd95b586f
Added delay after bus reset to comply with Maxim search algorithm; Tidied up search algorithm

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
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);
Bobty 7:0a87f8c2d9e6 66 return ONEWIRE_OK;
simonbarker 0:d961f715d82b 67 }
Bobty 5:45b6a39002f1 68 __enable_irq();
Bobty 7:0a87f8c2d9e6 69 return ONEWIRE_SEARCH_INIT_FAIL;
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 7:0a87f8c2d9e6 129 // Search Based on Maxim DS18B20 Algorithm
Bobty 7:0a87f8c2d9e6 130 // https://www.maximintegrated.com/en/app-notes/index.mvp/id/187
Bobty 1:8e9464e05ddf 131 //
Bobty 7:0a87f8c2d9e6 132 // Perform a search, returns:
Bobty 6:d2452e9b169b 133 // ONEWIRE_OK if a new address has been returned.
Bobty 6:d2452e9b169b 134 // ONEWIRE_SEARCH_ALL_DONE = all devices found
Bobty 6:d2452e9b169b 135 // ONEWIRE_SEARCH_INIT_FAIL = failed to init
Bobty 6:d2452e9b169b 136 // ONEWIRE_SEARCH_NOT_FOUND = no devices found If this function returns a '1' then it has
Bobty 7:0a87f8c2d9e6 137 // ONEWIRE_SEARCH_STUCK_HIGH = bus is stuck high
Bobty 7:0a87f8c2d9e6 138 // ONEWIRE_SEARCH_COMP_BIT_ERR = complement bit error
Bobty 1:8e9464e05ddf 139 //
Bobty 1:8e9464e05ddf 140 uint8_t Onewire::search(uint8_t *newAddr)
Bobty 1:8e9464e05ddf 141 {
Bobty 7:0a87f8c2d9e6 142 // initialize for search
Bobty 7:0a87f8c2d9e6 143 uint8_t last_zero = 0;
Bobty 7:0a87f8c2d9e6 144 unsigned char search_direction = 0;
Bobty 1:8e9464e05ddf 145
Bobty 7:0a87f8c2d9e6 146 // if the previous call was the last one
Bobty 7:0a87f8c2d9e6 147 if (_search_LastDeviceFlag)
Bobty 7:0a87f8c2d9e6 148 return ONEWIRE_SEARCH_ALL_DONE;
Bobty 7:0a87f8c2d9e6 149
Bobty 7:0a87f8c2d9e6 150 // 1-Wire reset
Bobty 7:0a87f8c2d9e6 151 int initRslt = init();
Bobty 7:0a87f8c2d9e6 152 wait_us(410);
Bobty 7:0a87f8c2d9e6 153 if (initRslt != ONEWIRE_OK)
Bobty 7:0a87f8c2d9e6 154 {
Bobty 7:0a87f8c2d9e6 155 // reset the search
Bobty 7:0a87f8c2d9e6 156 reset_search();
Bobty 7:0a87f8c2d9e6 157 return initRslt;
Bobty 7:0a87f8c2d9e6 158 }
Bobty 7:0a87f8c2d9e6 159
Bobty 7:0a87f8c2d9e6 160 // issue the search command
Bobty 7:0a87f8c2d9e6 161 writeByte(0xF0);
Bobty 7:0a87f8c2d9e6 162
Bobty 7:0a87f8c2d9e6 163 // loop to do the search
Bobty 7:0a87f8c2d9e6 164 for (int id_bit_number = 1; id_bit_number <= 64; id_bit_number++)
Bobty 7:0a87f8c2d9e6 165 {
Bobty 7:0a87f8c2d9e6 166 // read a bit and its complement
Bobty 7:0a87f8c2d9e6 167 uint8_t id_bit = readBit();
Bobty 7:0a87f8c2d9e6 168 uint8_t cmp_id_bit = readBit();
Bobty 7:0a87f8c2d9e6 169
Bobty 7:0a87f8c2d9e6 170 // check for no devices on 1-wire
Bobty 7:0a87f8c2d9e6 171 if ((id_bit == 1) && (cmp_id_bit == 1))
Bobty 7:0a87f8c2d9e6 172 {
Bobty 7:0a87f8c2d9e6 173 reset_search();
Bobty 7:0a87f8c2d9e6 174 return ONEWIRE_SEARCH_COMP_BIT_ERR;
Bobty 7:0a87f8c2d9e6 175 }
Bobty 1:8e9464e05ddf 176
Bobty 7:0a87f8c2d9e6 177 // all devices coupled have 0 or 1
Bobty 7:0a87f8c2d9e6 178 int byteNo = (id_bit_number - 1) / 8;
Bobty 7:0a87f8c2d9e6 179 int byteMask = 1 << ((id_bit_number - 1) % 8);
Bobty 7:0a87f8c2d9e6 180 if (id_bit != cmp_id_bit)
Bobty 7:0a87f8c2d9e6 181 {
Bobty 7:0a87f8c2d9e6 182 search_direction = id_bit; // bit write value for search
Bobty 7:0a87f8c2d9e6 183 }
Bobty 7:0a87f8c2d9e6 184 else
Bobty 7:0a87f8c2d9e6 185 {
Bobty 7:0a87f8c2d9e6 186 if (id_bit_number == _search_LastDiscrepancy)
Bobty 7:0a87f8c2d9e6 187 {
Bobty 7:0a87f8c2d9e6 188 search_direction = 1;
Bobty 7:0a87f8c2d9e6 189 }
Bobty 7:0a87f8c2d9e6 190 else if (id_bit_number > _search_LastDiscrepancy)
Bobty 7:0a87f8c2d9e6 191 {
Bobty 7:0a87f8c2d9e6 192 search_direction = 0;
Bobty 7:0a87f8c2d9e6 193 }
Bobty 1:8e9464e05ddf 194 else
Bobty 1:8e9464e05ddf 195 {
Bobty 7:0a87f8c2d9e6 196 search_direction = ((_search_ROM_NO[byteNo] & byteMask) > 0);
Bobty 1:8e9464e05ddf 197 }
Bobty 7:0a87f8c2d9e6 198
Bobty 7:0a87f8c2d9e6 199 // if 0 was picked then record its position in LastZero
Bobty 7:0a87f8c2d9e6 200 if (search_direction == 0)
Bobty 1:8e9464e05ddf 201 {
Bobty 7:0a87f8c2d9e6 202 last_zero = id_bit_number;
Bobty 7:0a87f8c2d9e6 203 // check for Last discrepancy in family
Bobty 7:0a87f8c2d9e6 204 if (last_zero < 9)
Bobty 7:0a87f8c2d9e6 205 _search_LastFamilyDiscrepancy = last_zero;
Bobty 1:8e9464e05ddf 206 }
Bobty 7:0a87f8c2d9e6 207 }
Bobty 7:0a87f8c2d9e6 208
Bobty 7:0a87f8c2d9e6 209 // set or clear the bit in the ROM byte rom_byte_number
Bobty 7:0a87f8c2d9e6 210 // with mask rom_byte_mask
Bobty 7:0a87f8c2d9e6 211
Bobty 7:0a87f8c2d9e6 212 if (search_direction == 1)
Bobty 7:0a87f8c2d9e6 213 _search_ROM_NO[byteNo] |= byteMask;
Bobty 7:0a87f8c2d9e6 214 else
Bobty 7:0a87f8c2d9e6 215 _search_ROM_NO[byteNo] &= ~byteMask;
Bobty 7:0a87f8c2d9e6 216
Bobty 7:0a87f8c2d9e6 217 // serial number search direction write bit
Bobty 7:0a87f8c2d9e6 218 writeBit(search_direction);
Bobty 7:0a87f8c2d9e6 219 }
Bobty 7:0a87f8c2d9e6 220
Bobty 7:0a87f8c2d9e6 221 // search successful so set LastDiscrepancy,LastDeviceFlag,search_result
Bobty 7:0a87f8c2d9e6 222 _search_LastDiscrepancy = last_zero;
Bobty 7:0a87f8c2d9e6 223 // check for last device
Bobty 7:0a87f8c2d9e6 224 if (_search_LastDiscrepancy == 0)
Bobty 7:0a87f8c2d9e6 225 _search_LastDeviceFlag = true;
Bobty 7:0a87f8c2d9e6 226
Bobty 7:0a87f8c2d9e6 227 // Copy address to return
Bobty 7:0a87f8c2d9e6 228 for (int i = 0; i < ONEWIRE_ADDR_BYTES; i++)
Bobty 7:0a87f8c2d9e6 229 newAddr[i] = _search_ROM_NO[i];
Bobty 7:0a87f8c2d9e6 230
Bobty 7:0a87f8c2d9e6 231 return ONEWIRE_OK;
Bobty 7:0a87f8c2d9e6 232 }
Bobty 1:8e9464e05ddf 233
Bobty 7:0a87f8c2d9e6 234 char* Onewire::GetErrorStr(int errCode)
Bobty 7:0a87f8c2d9e6 235 {
Bobty 7:0a87f8c2d9e6 236 switch(errCode)
Bobty 7:0a87f8c2d9e6 237 {
Bobty 7:0a87f8c2d9e6 238 case ONEWIRE_OK: return "OK";
Bobty 7:0a87f8c2d9e6 239 case ONEWIRE_SEARCH_ALL_DONE: return "All Done";
Bobty 7:0a87f8c2d9e6 240 case ONEWIRE_SEARCH_INIT_FAIL: return "Init Fail";
Bobty 7:0a87f8c2d9e6 241 case ONEWIRE_SEARCH_NOT_FOUND: return "Not Found";
Bobty 7:0a87f8c2d9e6 242 case ONEWIRE_SEARCH_STUCK_HIGH: return "Stuck High";
Bobty 7:0a87f8c2d9e6 243 case ONEWIRE_SEARCH_COMP_BIT_ERR: return "Comp Bit Err";
Bobty 7:0a87f8c2d9e6 244 }
Bobty 7:0a87f8c2d9e6 245 return "Unknown Err";
Bobty 7:0a87f8c2d9e6 246 }
Bobty 7:0a87f8c2d9e6 247