Library to communicate with Maxim OneWire protocol devices Modified timings and IRQ overrides
Fork of Onewire by
Diff: Onewire.cpp
- Revision:
- 7:0a87f8c2d9e6
- Parent:
- 6:d2452e9b169b
- Child:
- 8:5d0bd95b586f
--- a/Onewire.cpp Mon Oct 05 14:03:29 2015 +0000 +++ b/Onewire.cpp Thu Oct 15 21:39:21 2015 +0000 @@ -63,10 +63,10 @@ { __enable_irq(); wait_us(100); - return 1; + return ONEWIRE_OK; } __enable_irq(); - return 0; + return ONEWIRE_SEARCH_INIT_FAIL; } int Onewire::readByte() @@ -126,141 +126,122 @@ _search_ROM_NO[i] = 0; } -// Search Copied from Arduino code +// Search Based on Maxim DS18B20 Algorithm +// https://www.maximintegrated.com/en/app-notes/index.mvp/id/187 // -// Perform a search. -// Returns +// Perform a search, returns: // ONEWIRE_OK if a new address has been returned. // ONEWIRE_SEARCH_ALL_DONE = all devices found // ONEWIRE_SEARCH_INIT_FAIL = failed to init // ONEWIRE_SEARCH_NOT_FOUND = no devices found If this function returns a '1' then it has -// enumerated the next device and you may retrieve the ROM from the -// Onewire::address variable. If there are no devices, no further -// devices, or something horrible happens in the middle of the -// enumeration then a 0 is returned. If a new device is found then -// its address is copied to newAddr. Use Onewire::reset_search() to -// start over. -// -// --- Replaced by the one from the Dallas Semiconductor web site --- -//-------------------------------------------------------------------------- -// Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing -// search state. -// Return TRUE : device found, ROM number in ROM_NO buffer -// FALSE : device not found, end of search +// ONEWIRE_SEARCH_STUCK_HIGH = bus is stuck high +// ONEWIRE_SEARCH_COMP_BIT_ERR = complement bit error // uint8_t Onewire::search(uint8_t *newAddr) { - uint8_t id_bit_number = 1; - uint8_t last_zero = 0, rom_byte_number = 0; - uint8_t search_result = ONEWIRE_SEARCH_ALL_DONE; - uint8_t id_bit = 0, cmp_id_bit = 0; - - // initialize for search - unsigned char rom_byte_mask = 1, search_direction = 0; + // initialize for search + uint8_t last_zero = 0; + unsigned char search_direction = 0; - // if the last call was not the last one - if (!_search_LastDeviceFlag) - { - // 1-Wire reset - if (!init()) - { - // reset the search - _search_LastDiscrepancy = 0; - _search_LastDeviceFlag = false; - _search_LastFamilyDiscrepancy = 0; - return ONEWIRE_SEARCH_INIT_FAIL; - } - - // issue the search command - writeByte(0xF0); + // if the previous call was the last one + if (_search_LastDeviceFlag) + return ONEWIRE_SEARCH_ALL_DONE; + + // 1-Wire reset + int initRslt = init(); + wait_us(410); + if (initRslt != ONEWIRE_OK) + { + // reset the search + reset_search(); + return initRslt; + } + + // issue the search command + writeByte(0xF0); + + // loop to do the search + for (int id_bit_number = 1; id_bit_number <= 64; id_bit_number++) + { + // read a bit and its complement + uint8_t id_bit = readBit(); + uint8_t cmp_id_bit = readBit(); + + // check for no devices on 1-wire + if ((id_bit == 1) && (cmp_id_bit == 1)) + { + reset_search(); + return ONEWIRE_SEARCH_COMP_BIT_ERR; + } - // loop to do the search - do - { - // read a bit and its complement - id_bit = readBit(); - cmp_id_bit = readBit(); - - // check for no devices on 1-wire - if ((id_bit == 1) && (cmp_id_bit == 1)) - break; - else - { - // all devices coupled have 0 or 1 - if (id_bit != cmp_id_bit) - search_direction = id_bit; // bit write value for search + // all devices coupled have 0 or 1 + int byteNo = (id_bit_number - 1) / 8; + int byteMask = 1 << ((id_bit_number - 1) % 8); + if (id_bit != cmp_id_bit) + { + search_direction = id_bit; // bit write value for search + } + else + { + if (id_bit_number == _search_LastDiscrepancy) + { + search_direction = 1; + } + else if (id_bit_number > _search_LastDiscrepancy) + { + search_direction = 0; + } else { - // if this discrepancy if before the Last Discrepancy - // on a previous next then pick the same as last time - if (id_bit_number < _search_LastDiscrepancy) - search_direction = ((_search_ROM_NO[rom_byte_number] & rom_byte_mask) > 0); - else - // if equal to last pick 1, if not then pick 0 - search_direction = (id_bit_number == _search_LastDiscrepancy); - - // if 0 was picked then record its position in LastZero - if (search_direction == 0) - { - last_zero = id_bit_number; - - // check for Last discrepancy in family - if (last_zero < 9) - _search_LastFamilyDiscrepancy = last_zero; - } + search_direction = ((_search_ROM_NO[byteNo] & byteMask) > 0); } - - // set or clear the bit in the ROM byte rom_byte_number - // with mask rom_byte_mask - if (search_direction == 1) - _search_ROM_NO[rom_byte_number] |= rom_byte_mask; - else - _search_ROM_NO[rom_byte_number] &= ~rom_byte_mask; - - // serial number search direction write bit - writeBit(search_direction); - - // increment the byte counter id_bit_number - // and shift the mask rom_byte_mask - id_bit_number++; - rom_byte_mask <<= 1; - - // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask - if (rom_byte_mask == 0) + + // if 0 was picked then record its position in LastZero + if (search_direction == 0) { - rom_byte_number++; - rom_byte_mask = 1; + last_zero = id_bit_number; + // check for Last discrepancy in family + if (last_zero < 9) + _search_LastFamilyDiscrepancy = last_zero; } - } - } - while(rom_byte_number < ONEWIRE_ADDR_BYTES); // loop until through all ROM bytes 0-7 - - // if the search was successful then - if (!(id_bit_number < 65)) - { - // search successful so set LastDiscrepancy,LastDeviceFlag,search_result - _search_LastDiscrepancy = last_zero; - - // check for last device - if (_search_LastDiscrepancy == 0) - _search_LastDeviceFlag = true; + } + + // set or clear the bit in the ROM byte rom_byte_number + // with mask rom_byte_mask + + if (search_direction == 1) + _search_ROM_NO[byteNo] |= byteMask; + else + _search_ROM_NO[byteNo] &= ~byteMask; + + // serial number search direction write bit + writeBit(search_direction); + } + + // search successful so set LastDiscrepancy,LastDeviceFlag,search_result + _search_LastDiscrepancy = last_zero; + // check for last device + if (_search_LastDiscrepancy == 0) + _search_LastDeviceFlag = true; + + // Copy address to return + for (int i = 0; i < ONEWIRE_ADDR_BYTES; i++) + newAddr[i] = _search_ROM_NO[i]; + + return ONEWIRE_OK; +} - search_result = ONEWIRE_OK; - } - } - - // if no device found then reset counters so next 'search' will be like a first - if (!_search_ROM_NO[0]) - { - _search_LastDiscrepancy = 0; - _search_LastDeviceFlag = false; - _search_LastFamilyDiscrepancy = 0; - search_result = ONEWIRE_SEARCH_NOT_FOUND; - } - if (search_result != ONEWIRE_OK) - return search_result; - for (int i = 0; i < ONEWIRE_ADDR_BYTES; i++) - newAddr[i] = _search_ROM_NO[i]; - return search_result; - } - +char* Onewire::GetErrorStr(int errCode) +{ + switch(errCode) + { + case ONEWIRE_OK: return "OK"; + case ONEWIRE_SEARCH_ALL_DONE: return "All Done"; + case ONEWIRE_SEARCH_INIT_FAIL: return "Init Fail"; + case ONEWIRE_SEARCH_NOT_FOUND: return "Not Found"; + case ONEWIRE_SEARCH_STUCK_HIGH: return "Stuck High"; + case ONEWIRE_SEARCH_COMP_BIT_ERR: return "Comp Bit Err"; + } + return "Unknown Err"; +} +