Library to communicate with Maxim OneWire protocol devices Modified timings and IRQ overrides
Fork of Onewire by
Onewire.cpp
- Committer:
- Bobty
- Date:
- 2015-02-21
- Revision:
- 4:b678c7c8203c
- Parent:
- 3:712bf8967b68
- Child:
- 5:45b6a39002f1
File content as of revision 4:b678c7c8203c:
// Code derived from a number of sources including: // simonbarker on MBED // The search code is a port of Jim Studt's Adruino One Wire lib // Can handle multiple devices per pin // Rob Dobson, 2015 #include "Onewire.h" Onewire::Onewire(PinName oneBus):oneBus_(oneBus) { } void Onewire::writeBit(int bit) { bit = bit & 0x01; if (bit) { // Write '1' bit oneBus_.output(); oneBus_ = 0; wait_us(5); oneBus_.input(); wait_us(60); } else { // Write '0' bit oneBus_.output(); oneBus_ = 0; wait_us(70); oneBus_.input(); wait_us(2); } } int Onewire::readBit() { char result; oneBus_.output(); oneBus_ = 0; wait_us(1); oneBus_.input(); wait_us(5); result = oneBus_.read(); wait_us(55); return result; } int Onewire::init() { oneBus_.output(); oneBus_ = 0; wait_us(480); oneBus_.input(); wait_us(60); if (oneBus_.read() == 0) { wait(0.0001); return 1; } return 0; } int Onewire::readByte() { int result = 0; for (int loop = 0; loop < ONEWIRE_ADDR_BYTES; loop++) { // shift the result to get it ready for the next bit result >>= 1; // if result is one, then set MS bit if (readBit()) result |= 0x80; } return result; } void Onewire::writeByte(char data) { // Loop to write each bit in the byte, LS-bit first for (int loop = 0; loop < ONEWIRE_ADDR_BYTES; loop++) { writeBit(data & 0x01); // shift the data byte for the next bit data >>= 1; } } unsigned char Onewire::CRC(unsigned char* addr, unsigned char len) { unsigned char i, j; unsigned char crc = 0; for (i = 0; i < len; i++) { unsigned char inbyte = addr[i]; for (j = 0; j < ONEWIRE_ADDR_BYTES; j++) { unsigned char mix = (crc ^ inbyte) & 0x01; crc >>= 1; if (mix) crc ^= 0x8C; inbyte >>= 1; } } return crc; } // // You need to use this function to start a search again from the beginning. // You do not need to do it for the first search, though you could. // void Onewire::reset_search() { // reset the search state _search_LastDiscrepancy = 0; _search_LastDeviceFlag = false; _search_LastFamilyDiscrepancy = 0; for(int i = ONEWIRE_ADDR_BYTES-1; i >= 0; i--) _search_ROM_NO[i] = 0; } // Search Copied from Arduino code // // Perform a search. 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 // uint8_t Onewire::search(uint8_t *newAddr) { uint8_t id_bit_number = 1; uint8_t last_zero = 0, rom_byte_number = 0, search_result = 0; uint8_t id_bit = 0, cmp_id_bit = 0; // initialize for search unsigned char rom_byte_mask = 1, 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 false; } // issue the search command writeByte(0xF0); // 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 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; } } // 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) { rom_byte_number++; rom_byte_mask = 1; } } } 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; search_result = true; } } // if no device found then reset counters so next 'search' will be like a first if (!search_result || !_search_ROM_NO[0]) { _search_LastDiscrepancy = 0; _search_LastDeviceFlag = false; _search_LastFamilyDiscrepancy = 0; search_result = false; } for (int i = 0; i < ONEWIRE_ADDR_BYTES; i++) newAddr[i] = _search_ROM_NO[i]; return search_result; }