Implementation of 1-Wire with added Alarm Search Functionality
Dependents: Max32630_One_Wire_Interface
Diff: Masters/OneWireMaster.cpp
- Revision:
- 74:23be10c32fa3
- Parent:
- 73:2cecc1372acc
- Child:
- 75:8b627804927c
--- a/Masters/OneWireMaster.cpp Thu May 12 14:38:16 2016 -0500 +++ b/Masters/OneWireMaster.cpp Fri May 13 07:48:35 2016 -0500 @@ -51,16 +51,16 @@ OneWireMaster::CmdResult OneWireMaster::OWWriteBlock(const uint8_t *tran_buf, uint8_t tran_len) { CmdResult result; - - for(uint8_t idx = 0; idx < tran_len; idx++) + + for (uint8_t idx = 0; idx < tran_len; idx++) { result = OWWriteByte(tran_buf[idx]); - if(result != Success) + if (result != Success) { break; } } - + return result; } @@ -69,16 +69,16 @@ OneWireMaster::CmdResult OneWireMaster::OWReadBlock(uint8_t *rx_buf, uint8_t rx_len) { CmdResult result; - - for(uint8_t idx = 0; idx < rx_len; idx++) + + for (uint8_t idx = 0; idx < rx_len; idx++) { result = OWReadByte(rx_buf[idx]); - if(result != Success) + if (result != Success) { break; } } - + return result; } @@ -88,7 +88,7 @@ // reset the search state searchState.reset(); - return OWSearch(searchState); + return OWSearch(searchState); } @@ -105,7 +105,7 @@ { OneWireMaster::CmdResult result; SearchState searchState; - + searchState.romId = romId; // set search to find the same device @@ -113,10 +113,10 @@ searchState.last_device_flag = false; result = OWSearch(searchState); - if (result == OneWireMaster::Success) + if (result == OneWireMaster::Success) { // check if same device found - if (romId != searchState.romId) + if (romId != searchState.romId) { result = OneWireMaster::OperationFailure; } @@ -171,42 +171,42 @@ { result = OWReadBlock(buf, RomId::byteLen); } - + // verify CRC8 if ((result == OneWireMaster::Success) && (RomId::calculateCRC8(buf, RomId::byteLen) == 0)) { - romId = RomId(reinterpret_cast<uint8_t (&)[RomId::byteLen]>(buf[0])); + romId = RomId(reinterpret_cast<uint8_t(&)[RomId::byteLen]>(buf[0])); } return result; } - + //********************************************************************* OneWireMaster::CmdResult OneWireMaster::OWSkipROM(void) { OneWireMaster::CmdResult result; - + result = OWReset(); - if (result == OneWireMaster::Success) + if (result == OneWireMaster::Success) { result = OWWriteByte(SKIP_ROM); } - + return result; } - + //********************************************************************* OneWireMaster::CmdResult OneWireMaster::OWMatchROM(const RomId & romId) { OneWireMaster::CmdResult result; - + uint8_t buf[1 + RomId::byteLen]; // use MatchROM result = OWReset(); - if (result == OneWireMaster::Success) + if (result == OneWireMaster::Success) { buf[0] = MATCH_ROM; std::memcpy(&buf[1], romId, RomId::byteLen); @@ -216,45 +216,45 @@ return result; } - + //********************************************************************* OneWireMaster::CmdResult OneWireMaster::OWOverdriveSkipROM(void) { OneWireMaster::CmdResult result = OWSetSpeed(SPEED_STANDARD); - + if (result == OneWireMaster::Success) { result = OWReset(); } - + if (result == OneWireMaster::Success) { result = OWWriteByte(OVERDRIVE_SKIP_ROM); } - + if (result == OneWireMaster::Success) { result = OWSetSpeed(SPEED_OVERDRIVE); } - + return result; } - + //********************************************************************* OneWireMaster::CmdResult OneWireMaster::OWOverdriveMatchROM(const RomId & romId) { OneWireMaster::CmdResult result; - + // use overdrive MatchROM OWSetSpeed(SPEED_STANDARD); - + result = OWReset(); - if (result == OneWireMaster::Success) + if (result == OneWireMaster::Success) { result = OWWriteByte(OVERDRIVE_MATCH_ROM); - if (result == OneWireMaster::Success) + if (result == OneWireMaster::Success) { OWSetSpeed(SPEED_OVERDRIVE); // send ROM @@ -263,140 +263,159 @@ } return result; } - + //********************************************************************* OneWireMaster::CmdResult OneWireMaster::OWResume(void) { OneWireMaster::CmdResult result; - + result = OWReset(); - if (result == OneWireMaster::Success) + if (result == OneWireMaster::Success) { result = OWWriteByte(RESUME); } - + return result; } OneWireMaster::CmdResult OneWireMaster::OWSearch(SearchState & searchState) { - uint8_t id_bit_number; - uint8_t last_zero, rom_byte_number; - uint8_t id_bit, cmp_id_bit; - uint8_t rom_byte_mask; - bool search_result; - uint8_t crc8 = 0; - SearchDirection search_direction; + uint8_t id_bit_number; + uint8_t last_zero, rom_byte_number; + uint8_t id_bit, cmp_id_bit; + uint8_t rom_byte_mask; + bool search_result; + uint8_t crc8 = 0; + SearchDirection search_direction; - // initialize for search - id_bit_number = 1; - last_zero = 0; - rom_byte_number = 0; - rom_byte_mask = 1; - search_result = false; + // initialize for search + id_bit_number = 1; + last_zero = 0; + rom_byte_number = 0; + rom_byte_mask = 1; + search_result = false; - // if the last call was not the last one - if (!searchState.last_device_flag) - { - // 1-Wire reset - OneWireMaster::CmdResult result = OWReset(); - if (result != OneWireMaster::Success) - { - // reset the search - searchState.reset(); - return result; - } + // if the last call was not the last one + if (!searchState.last_device_flag) + { + // 1-Wire reset + OneWireMaster::CmdResult result = OWReset(); + if (result != OneWireMaster::Success) + { + // reset the search + searchState.reset(); + return result; + } - // issue the search command - OneWireMaster::OWWriteByte(SEARCH_ROM); + // issue the search command + OneWireMaster::OWWriteByte(SEARCH_ROM); - // loop to do the search - do - { - // if this discrepancy if before the Last Discrepancy - // on a previous next then pick the same as last time - if (id_bit_number < searchState.last_discrepancy) - { - if ((searchState.romId[rom_byte_number] & rom_byte_mask) > 0) - search_direction = DIRECTION_WRITE_ONE; - else - search_direction = DIRECTION_WRITE_ZERO; - } - else - { - // if equal to last pick 1, if not then pick 0 - if (id_bit_number == searchState.last_discrepancy) - search_direction = DIRECTION_WRITE_ONE; + // loop to do the search + do + { + // if this discrepancy if before the Last Discrepancy + // on a previous next then pick the same as last time + if (id_bit_number < searchState.last_discrepancy) + { + if ((searchState.romId[rom_byte_number] & rom_byte_mask) > 0) + { + search_direction = DIRECTION_WRITE_ONE; + } + else + { + search_direction = DIRECTION_WRITE_ZERO; + } + } else - search_direction = DIRECTION_WRITE_ZERO; - } - - // Peform a triple operation on the DS2465 which will perform 2 read bits and 1 write bit - result = OWTriplet(search_direction, id_bit, cmp_id_bit); - if (result != OneWireMaster::Success) - return result; + { + // if equal to last pick 1, if not then pick 0 + if (id_bit_number == searchState.last_discrepancy) + { + search_direction = DIRECTION_WRITE_ONE; + } + else + { + search_direction = DIRECTION_WRITE_ZERO; + } + } - // check for no devices on 1-wire - if ((id_bit) && (cmp_id_bit)) - break; - else - { - if ((!id_bit) && (!cmp_id_bit) && (search_direction == DIRECTION_WRITE_ZERO)) + // Peform a triple operation on the DS2465 which will perform 2 read bits and 1 write bit + result = OWTriplet(search_direction, id_bit, cmp_id_bit); + if (result != OneWireMaster::Success) { - last_zero = id_bit_number; - - // check for Last discrepancy in family - if (last_zero < 9) - searchState.last_family_discrepancy = last_zero; + return result; } - // set or clear the bit in the ROM byte rom_byte_number - // with mask rom_byte_mask - if (search_direction == DIRECTION_WRITE_ONE) - searchState.romId[rom_byte_number] |= rom_byte_mask; + // check for no devices on 1-wire + if ((id_bit) && (cmp_id_bit)) + { + break; + } else - searchState.romId[rom_byte_number] &= (uint8_t)~rom_byte_mask; + { + if ((!id_bit) && (!cmp_id_bit) && (search_direction == DIRECTION_WRITE_ZERO)) + { + last_zero = id_bit_number; - // increment the byte counter id_bit_number - // and shift the mask rom_byte_mask - id_bit_number++; - rom_byte_mask <<= 1; + // check for Last discrepancy in family + if (last_zero < 9) + { + searchState.last_family_discrepancy = last_zero; + } + } - // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask - if (rom_byte_mask == 0) - { - crc8 = RomId::calculateCRC8(crc8, searchState.romId[rom_byte_number]); // accumulate the CRC - rom_byte_number++; - rom_byte_mask = 1; - } - } - } - while(rom_byte_number < RomId::byteLen); // loop until through all ROM bytes 0-7 + // set or clear the bit in the ROM byte rom_byte_number + // with mask rom_byte_mask + if (search_direction == DIRECTION_WRITE_ONE) + { + searchState.romId[rom_byte_number] |= rom_byte_mask; + } + else + { + searchState.romId[rom_byte_number] &= (uint8_t)~rom_byte_mask; + } + + // increment the byte counter id_bit_number + // and shift the mask rom_byte_mask + id_bit_number++; + rom_byte_mask <<= 1; - // if the search was successful then - if (!((id_bit_number <= (RomId::byteLen * 8)) || (crc8 != 0))) - { - // search successful so set m_last_discrepancy,m_last_device_flag,search_result - searchState.last_discrepancy = last_zero; + // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask + if (rom_byte_mask == 0) + { + crc8 = RomId::calculateCRC8(crc8, searchState.romId[rom_byte_number]); // accumulate the CRC + rom_byte_number++; + rom_byte_mask = 1; + } + } + } while (rom_byte_number < RomId::byteLen); // loop until through all ROM bytes 0-7 - // check for last device - if (searchState.last_discrepancy == 0) - searchState.last_device_flag = true; + // if the search was successful then + if (!((id_bit_number <= (RomId::byteLen * 8)) || (crc8 != 0))) + { + // search successful so set m_last_discrepancy,m_last_device_flag,search_result + searchState.last_discrepancy = last_zero; - search_result = true; - } - } + // check for last device + if (searchState.last_discrepancy == 0) + { + searchState.last_device_flag = true; + } - // if no device found then reset counters so next 'search' will be like a first - if (!search_result || (searchState.romId.familyCode() == 0)) - { - searchState.reset(); - search_result = false; - } + search_result = true; + } + } - return search_result ? OneWireMaster::Success : OneWireMaster::OperationFailure; + // if no device found then reset counters so next 'search' will be like a first + if (!search_result || (searchState.romId.familyCode() == 0)) + { + searchState.reset(); + search_result = false; + } + + return (search_result ? OneWireMaster::Success : OneWireMaster::OperationFailure); } @@ -405,15 +424,21 @@ CmdResult result; result = OWReadBit(sbr); if (result == Success) + { result = OWReadBit(tsb); + } if (result == Success) { if (sbr) + { search_direction = DIRECTION_WRITE_ONE; + } else if (tsb) + { search_direction = DIRECTION_WRITE_ZERO; + } // else: use search_direction parameter - + result = OWWriteBit((search_direction == DIRECTION_WRITE_ONE) ? 1 : 0); } return result; @@ -422,26 +447,30 @@ uint16_t OneWireMaster::calculateCRC16(uint16_t CRC16, uint16_t data) { - const uint16_t _oddparity[] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; - - data = (data ^ (CRC16 & 0xff)) & 0xff; - CRC16 >>= 8; + const uint16_t _oddparity[] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; + + data = (data ^ (CRC16 & 0xff)) & 0xff; + CRC16 >>= 8; - if (_oddparity[data & 0xf] ^ _oddparity[data >> 4]) - CRC16 ^= 0xc001; + if (_oddparity[data & 0xf] ^ _oddparity[data >> 4]) + { + CRC16 ^= 0xc001; + } - data <<= 6; - CRC16 ^= data; - data <<= 1; - CRC16 ^= data; + data <<= 6; + CRC16 ^= data; + data <<= 1; + CRC16 ^= data; - return CRC16; + return CRC16; } uint16_t OneWireMaster::calculateCRC16(const uint8_t * data, size_t data_offset, size_t data_len, uint16_t crc) -{ - for (size_t i = data_offset; i < (data_len + data_offset); i++) - crc = calculateCRC16(crc, data[i]); - return crc; +{ + for (size_t i = data_offset; i < (data_len + data_offset); i++) + { + crc = calculateCRC16(crc, data[i]); + } + return crc; }