1-Wire® library for mbed. Complete 1-Wire library that supports our silicon masters along with a bit-bang master on the MAX32600MBED platform with one common interface for mbed. Slave support has also been included and more slaves will be added as time permits.
Dependents: MAXREFDES131_Qt_Demo MAX32630FTHR_iButton_uSD_Logger MAX32630FTHR_DS18B20_uSD_Logger MAXREFDES130_131_Demo ... more
Superseded by MaximInterface.
Diff: OneWire_Masters/DS2465/DS2465.cpp
- Revision:
- 24:8942d8478d68
- Parent:
- 22:686273e55cdc
- Child:
- 26:a361e3f42ba5
--- a/OneWire_Masters/DS2465/DS2465.cpp Mon Mar 21 23:18:45 2016 +0000 +++ b/OneWire_Masters/DS2465/DS2465.cpp Tue Mar 22 14:24:53 2016 -0500 @@ -23,12 +23,6 @@ #define CMD_CNMS 0x1E #define CMD_SPR 0x0F -// DS2465 config bits -#define CONFIG_APU 0x01 -#define CONFIG_PDN 0x02 -#define CONFIG_SPU 0x04 -#define CONFIG_1WS 0x08 - // DS2465 status bits #define STATUS_1WB 0x01 #define STATUS_PPD 0x02 @@ -46,6 +40,36 @@ static const int I2C_WRITE_OK = 0; + +std::uint8_t DS2465::Config::readByte() const +{ + std::uint8_t config = 0; + if (c1WS) + config |= 0x08; + if (cSPU) + config |= 0x04; + if (cPDN) + config |= 0x02; + if (cAPU) + config |= 0x01; + return config; +} + +std::uint8_t DS2465::Config::writeByte() const +{ + std::uint8_t config = readByte(); + return ((~config << 4) | config); +} + +void DS2465::Config::reset() +{ + c1WS = cSPU = cPDN = false; + cAPU = true; +} + + + + DS2465::DS2465(I2C & I2C_interface, unsigned char I2C_address) : m_I2C_interface(I2C_interface), m_I2C_address(I2C_address) { @@ -73,15 +97,8 @@ // OneWireMaster::CmdResult DS2465::Compute_NextMasterSecret(bool swap, unsigned int pageNum, PageRegion region) { - uint8_t par; - - // create parameter byte - if (!swap) - par = 0xBF; - else - par = (0xC8 | (pageNum << 4) | region); - - return Write_Command_Reg(CMD_CNMS, par, false); + uint8_t command[2] = { CMD_CNMS, (swap ? (0xC8 | (pageNum << 4) | region) : 0xBF) }; + return WriteMemory(ADDR_CMD_REG, command, 2); } //-------------------------------------------------------------------------- @@ -97,12 +114,8 @@ // OneWireMaster::CmdResult DS2465::Compute_WriteMAC(bool regwrite, bool swap, unsigned int pageNum, unsigned int segmentNum) const { - uint8_t par; - - // create parameter byte - par = ((regwrite << 7) | (swap << 6) | (pageNum << 4) | segmentNum); - - return Write_Command_Reg(CMD_CSWM, par, false); + uint8_t command[2] = { CMD_CSWM, ((regwrite << 7) | (swap << 6) | (pageNum << 4) | segmentNum) }; + return CWriteMemory(ADDR_CMD_REG, command, 2); } //-------------------------------------------------------------------------- @@ -117,15 +130,8 @@ // OneWireMaster::CmdResult DS2465::Compute_AuthMAC(bool swap, unsigned int pageNum, PageRegion region) const { - uint8_t par; - - // create parameter byte - if (!swap) - par = 0xBF; - else - par = (0xC8 | (pageNum << 4) | region); - - return Write_Command_Reg(CMD_CSAM, par, false); + uint8_t command[2] = { CMD_CSAM, (swap ? (0xC8 | (pageNum << 4) | region) : 0xBF) }; + return CWriteMemory(ADDR_CMD_REG, command, 2); } //-------------------------------------------------------------------------- @@ -140,15 +146,8 @@ // OneWireMaster::CmdResult DS2465::Compute_SSecret(bool swap, unsigned int pageNum, PageRegion region) { - uint8_t par; - - // create parameter byte - if (!swap) - par = 0xBF; - else - par = (0xC8 | (pageNum << 4) | region); - - return Write_Command_Reg(CMD_CSS, par, false); + uint8_t command[2] = { CMD_CSS, (swap ? (0xC8 | (pageNum << 4) | region) : 0xBF) }; + return WriteMemory(ADDR_CMD_REG, command, 2); } @@ -157,7 +156,7 @@ ISha256MacCoprocessor::CmdResult DS2465::setMasterSecret(const std::uint8_t (&secret)[secret_len]) { OneWireMaster::CmdResult result; - result = WriteScratchpad(ADDR_SPAD, secret, secret_len); + result = WriteMemory(ADDR_SPAD, secret, secret_len); if (result == OneWireMaster::Success) result = CopyScratchpad(1, 0, 1, 0); if (result == OneWireMaster::Success) @@ -169,7 +168,7 @@ { OneWireMaster::CmdResult result; // Write input data to scratchpad - result = WriteScratchpad(ADDR_SPAD, WriteMAC_data, WriteMAC_data_len); + result = WriteScratchpad(WriteMAC_data, WriteMAC_data_len); // Compute MAC if (result == OneWireMaster::Success) result = Compute_WriteMAC(false, false, 0, 0); @@ -188,16 +187,16 @@ OneWireMaster::CmdResult result; int addr = ADDR_SPAD; // Write input data to scratchpad - result = WriteScratchpad(addr, devicePage, devicePage_len); + result = CWriteMemory(addr, devicePage, devicePage_len); if (result == OneWireMaster::Success) { addr += devicePage_len; - result = WriteScratchpad(addr, challenge, deviceScratchpad_len); + result = CWriteMemory(addr, challenge, deviceScratchpad_len); } if (result == OneWireMaster::Success) { addr += deviceScratchpad_len; - result = WriteScratchpad(addr, AuthMAC_data, AuthMAC_data_len); + result = CWriteMemory(addr, AuthMAC_data, AuthMAC_data_len); } // Compute MAC if (result == OneWireMaster::Success) @@ -217,16 +216,16 @@ OneWireMaster::CmdResult result; int addr = ADDR_SPAD; // Write input data to scratchpad - result = WriteScratchpad(addr, devicePage, devicePage_len); + result = WriteMemory(addr, devicePage, devicePage_len); if (result == OneWireMaster::Success) { addr += devicePage_len; - result = WriteScratchpad(addr, deviceScratchpad, deviceScratchpad_len); + result = WriteMemory(addr, deviceScratchpad, deviceScratchpad_len); } if (result == OneWireMaster::Success) { addr += deviceScratchpad_len; - result = WriteScratchpad(addr, SSecret_data, SSecret_data_len); + result = WriteMemory(addr, SSecret_data, SSecret_data_len); } // Compute secret if (result == OneWireMaster::Success) @@ -249,15 +248,8 @@ // OneWireMaster::CmdResult DS2465::CopyScratchpad(bool dest_secret, unsigned int pageNum, bool notFull, unsigned int segmentNum) { - uint8_t par; - - // create parameter byte - if (dest_secret) - par = 0; - else - par = (0x80 | (pageNum << 4) | (notFull << 3) | segmentNum); - - return Write_Command_Reg(CMD_CPS, par, false); + uint8_t command[2] = { CMD_CPS, (dest_secret ? 0 : (0x80 | (pageNum << 4) | (notFull << 3) | segmentNum)) }; + return WriteMemory(ADDR_CMD_REG, command, 2); } //-------------------------------------------------------------------------- @@ -271,10 +263,10 @@ OneWireMaster::CmdResult DS2465::ConfigureAPU(bool apu_enable) { // clear power down bit in the global config state - cAPU = apu_enable ? CONFIG_APU : 0; + m_curConfig.cAPU = apu_enable; // write the new config - return Write_Config(c1WS | cSPU | cPDN | cAPU); + return WriteConfig(m_curConfig); } //-------------------------------------------------------------------------- @@ -288,10 +280,10 @@ OneWireMaster::CmdResult rt; // clear power down bit in the global config state - cPDN = 0; + m_curConfig.cPDN = false; // write the new config - rt = Write_Config(c1WS | cSPU | cPDN | cAPU); + rt = WriteConfig(m_curConfig); // delay 2ms to allow units to power up wait_ms(2); @@ -308,10 +300,10 @@ OneWireMaster::CmdResult DS2465::OWPowerDown(void) { // set power down bit in the global config state - cPDN = CONFIG_PDN; + m_curConfig.cPDN = true; // write the new config - return Write_Config(c1WS | cSPU | cPDN | cAPU); + return WriteConfig(m_curConfig); } //-------------------------------------------------------------------------- @@ -332,10 +324,10 @@ uint8_t rdbit; // set strong pull-up enable - cSPU = CONFIG_SPU; + m_curConfig.cSPU = true; // write the new config - result = Write_Config(c1WS | cSPU | cPDN | cAPU); + result = WriteConfig(m_curConfig); if (result != OneWireMaster::Success) return result; @@ -365,10 +357,10 @@ OneWireMaster::CmdResult result; // set strong pull-up enable - cSPU = CONFIG_SPU; + m_curConfig.cSPU = true; // write the new config - result = Write_Config(c1WS | cSPU | cPDN | cAPU); + result = WriteConfig(m_curConfig); if (result != OneWireMaster::Success) return result; @@ -390,10 +382,10 @@ OneWireMaster::CmdResult result; // set strong pull-up enable - cSPU = CONFIG_SPU; + m_curConfig.cSPU = true; // write the new config - result = Write_Config(c1WS | cSPU | cPDN | cAPU); + result = WriteConfig(m_curConfig); if (result != OneWireMaster::Success) return result; @@ -419,141 +411,10 @@ return OneWireMaster::OperationFailure; // clear the strong pull-up bit in the global config state - cSPU = 0; + m_curConfig.cSPU = false; // write the new config - return Write_Config(c1WS | cSPU | cPDN | cAPU); -} - -//-------------------------------------------------------------------------- -// The 'OWOverdriveMatchROM' function does an overdrive Match-ROM using the -// global ROM_NO device -// -// Returns: true (1) : OWReset successful and match rom sent. -// false (0): OWReset did not have presence -// -OneWireMaster::CmdResult DS2465::OWOverdriveMatchROM(const RomId & romId) -{ - OneWireMaster::CmdResult result; - // use overdrive MatchROM - OWSpeed(SPEED_STANDARD); - result = OWReset(); - if (result == OneWireMaster::Success) - { - result = OWWriteByte(0x69); - if (result == OneWireMaster::Success) - { - OWSpeed(SPEED_OVERDRIVE); - // send ROM - result = OWWriteBlock(false, romId, RomId::byteLen); - } - } - return result; -} - -//-------------------------------------------------------------------------- -// The 'OWMatchROM' function does a Match-ROM using the global ROM_NO device -// -// Returns: true (1) : OWReset successful and match rom sent. -// false (0): OWReset did not have presence -// -OneWireMaster::CmdResult DS2465::OWMatchROM(const RomId & romId) -{ - OneWireMaster::CmdResult result; - uint8_t buf[1 + RomId::byteLen]; - - // use MatchROM - result = OWReset(); - if (result == OneWireMaster::Success) - { - buf[0] = 0x55; - std::memcpy(&buf[1], romId, RomId::byteLen); - // send command and rom - result = OWWriteBlock(false, buf, 1 + RomId::byteLen); - } - - return result; -} - -//-------------------------------------------------------------------------- -// Setup the search to skip the current device type on the next call -// to OWNext(). -// -void DS2465::OWFamilySkipSetup(void) -{ - // set the Last discrepancy to last family discrepancy - m_lastDiscrepancy = m_lastFamilyDiscrepancy; - - // clear the last family discrpepancy - m_lastFamilyDiscrepancy = 0; - - // check for end of list - if (m_lastDiscrepancy == 0) - m_lastDeviceFlag = true; -} - -//-------------------------------------------------------------------------- -// Setup the search to find the device type 'family_code' on the next call -// to OWNext() if it is present. -// -void DS2465::OWTargetSetup(RomId & romId) -{ - // set the search state to find SearchFamily type devices - for (int i = 1; i < 8; i++) - romId[i] = 0; - m_lastDiscrepancy = 64; - m_lastFamilyDiscrepancy = 0; - m_lastDeviceFlag = false; -} - -//-------------------------------------------------------------------------- -// Verify the device with the ROM number in ROM_NO buffer is present. -// Return true : device verified present -// false : device not present -// -OneWireMaster::CmdResult DS2465::OWVerify(const RomId & romId) -{ - OneWireMaster::CmdResult result; - RomId romIdCopy(romId); - int ld_backup, ldf_backup, lfd_backup; - - // keep a backup copy of the current state - ld_backup = m_lastDiscrepancy; - ldf_backup = m_lastDeviceFlag; - lfd_backup = m_lastFamilyDiscrepancy; - - // set search to find the same device - m_lastDiscrepancy = 64; - m_lastDeviceFlag = false; - - result = OWSearch(romIdCopy); - if (result == OneWireMaster::Success) - { - // check if same device found - if (romId != romIdCopy) - { - result = OneWireMaster::OperationFailure; - } - } - - // restore the search state - m_lastDiscrepancy = ld_backup; - m_lastDeviceFlag = ldf_backup; - m_lastFamilyDiscrepancy = lfd_backup; - - // return the result of the verify - return result; -} - -//-------------------------------------------------------------------------- -// Find the 'next' devices on the 1-Wire network -// Return true : device found, ROM number in ROM_NO buffer -// false : device not found, end of search -// -OneWireMaster::CmdResult DS2465::OWNext(RomId & romId) -{ - // leave the search state alone - return OWSearch(romId); + return WriteConfig(m_curConfig); } //-------------------------------------------------------------------------- @@ -567,96 +428,11 @@ // OneWireMaster::CmdResult DS2465::OWSpeed(OW_SPEED new_speed) { - // set the speed - if (new_speed == SPEED_OVERDRIVE) - c1WS = CONFIG_1WS; - else - c1WS = 0; + // set the speed + m_curConfig.c1WS = (new_speed == SPEED_OVERDRIVE); // write the new config - return Write_Config(c1WS | cSPU | cPDN | cAPU); -} - -//-------------------------------------------------------------------------- -// The 'OWOverdriveSkipROM' function does an Overdrive skip-ROM. Ignores -// result from standard speed OWReset(). -// -// Returns: true (1) : OWReset and skip rom sent. -// false (0): Could not change to overdrive -// -OneWireMaster::CmdResult DS2465::OWOverdriveSkipROM(void) -{ - OneWireMaster::CmdResult result = OWSpeed(SPEED_STANDARD); - if (result == OneWireMaster::Success) - result = OWReset(); - if (result == OneWireMaster::Success) - result = OWWriteByte(0x3C); - if (result == OneWireMaster::Success) - result = OWSpeed(SPEED_OVERDRIVE); - return result; -} - -//-------------------------------------------------------------------------- -// The 'OWResume' function does a Resume command 0xA5. -// -// Returns: true (1) : OWReset successful and RESUME sent. -// false (0): OWReset did not have presence -// -OneWireMaster::CmdResult DS2465::OWResume(void) -{ - OneWireMaster::CmdResult result; - result = OWReset(); - if (result == OneWireMaster::Success) - { - result = OWWriteByte(0xA5); - } - return result; -} - -//-------------------------------------------------------------------------- -// The 'OWSkipROM' function does a skip-ROM. This function -// uses the Skip-ROM function CCh. -// -// Returns: true (1) : OWReset successful and skip rom sent. -// false (0): OWReset did not have presence -// -OneWireMaster::CmdResult DS2465::OWSkipROM(void) -{ - OneWireMaster::CmdResult result; - result = OWReset(); - if (result == OneWireMaster::Success) - { - result = OWWriteByte(0xCC); - } - return result; -} - -//-------------------------------------------------------------------------- -// The 'OWReadROM' function does a Read-ROM. This function -// uses the read-ROM function 33h to read a ROM number and verify CRC8. -// -// Returns: true (1) : OWReset successful and Serial Number placed -// in the global ROM, CRC8 valid -// false (0): OWReset did not have presence or CRC8 invalid -// -OneWireMaster::CmdResult DS2465::OWReadROM(RomId & romId) -{ - OneWireMaster::CmdResult result; - uint8_t buf[2 + RomId::byteLen]; - - result = OWReset(); - if (result == OneWireMaster::Success) - result = OWWriteByte(0x33); // READ ROM - - // read the ROM - if (result == OneWireMaster::Success) - result = OWReadBlock(buf, RomId::byteLen); - - // verify CRC8 - if ((result == OneWireMaster::Success) && (RomId::calculateCRC8(buf, RomId::byteLen) == 0) && (buf[1] != 0)) - romId = RomId(reinterpret_cast<std::uint8_t (&)[RomId::byteLen]>(buf[0])); - - return result; + return WriteConfig(m_curConfig); } //-------------------------------------------------------------------------- @@ -669,67 +445,19 @@ // OneWireMaster::CmdResult DS2465::Triplet(Direction search_direction, uint8_t & status) { - int poll_count = 0; - // 1-Wire Triplet (Case B) // S AD,0 [A] 1WT [A] SS [A] Sr AD,1 [A] [Status] A [Status] A\ P // \--------/ // Repeat until 1WB bit has changed to 0 // [] indicates from slave // SS indicates byte containing search direction bit value in msbit - - m_I2C_interface.start(); - if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write(CMD_1WT) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write((unsigned char)((search_direction == DIRECTION_WRITE_ONE) ? 0x80 : 0x00)) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - m_I2C_interface.start(); - if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_READ)) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - - // loop checking 1WB bit for completion of 1-Wire operation - // abort if poll limit reached - status = STATUS_1WB; - while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT)) - { - status = m_I2C_interface.read(status & STATUS_1WB); - } - - // one last read with NACK - m_I2C_interface.read(m_I2C_interface.NoACK); - - m_I2C_interface.stop(); - - // check for failure due to poll limit reached - if (poll_count >= POLL_LIMIT) - { - // handle error - // ... - Reset(); - return OneWireMaster::TimeoutError; - } - - // return status byte - return OneWireMaster::Success; + + OneWireMaster::CmdResult result; + uint8_t command[2] = { CMD_1WT, ((search_direction == DIRECTION_WRITE_ONE) ? 0x80 : 0x00) }; + result = WriteMemory(ADDR_CMD_REG, command, 2); + if (result == OneWireMaster::Success) + result = PollBusy(&status); + return result; } //-------------------------------------------------------------------------- @@ -766,16 +494,16 @@ search_result = false; // if the last call was not the last one - if (!m_lastDeviceFlag) + if (!_last_device_flag) { // 1-Wire reset OneWireMaster::CmdResult result = OWReset(); if (result != OneWireMaster::Success) { // reset the search - m_lastDiscrepancy = 0; - m_lastDeviceFlag = false; - m_lastFamilyDiscrepancy = 0; + _last_discrepancy = 0; + _last_device_flag = false; + _last_family_discrepancy = 0; return result; } @@ -787,7 +515,7 @@ { // if this discrepancy if before the Last Discrepancy // on a previous next then pick the same as last time - if (id_bit_number < m_lastDiscrepancy) + if (id_bit_number < _last_discrepancy) { if ((romId[rom_byte_number] & rom_byte_mask) > 0) search_direction = DIRECTION_WRITE_ONE; @@ -797,7 +525,7 @@ else { // if equal to last pick 1, if not then pick 0 - if (id_bit_number == m_lastDiscrepancy) + if (id_bit_number == _last_discrepancy) search_direction = DIRECTION_WRITE_ONE; else search_direction = DIRECTION_WRITE_ZERO; @@ -822,7 +550,7 @@ // check for Last discrepancy in family if (last_zero < 9) - m_lastFamilyDiscrepancy = last_zero; + _last_family_discrepancy = last_zero; } // set or clear the bit in the ROM byte rom_byte_number @@ -851,12 +579,12 @@ // if the search was successful then if (!((id_bit_number <= (RomId::byteLen * 8)) || (crc8 != 0))) { - // search successful so set m_lastDiscrepancy,m_lastDeviceFlag,search_result - m_lastDiscrepancy = last_zero; + // search successful so set m_last_discrepancy,m_last_device_flag,search_result + _last_discrepancy = last_zero; // check for last device - if (m_lastDiscrepancy == 0) - m_lastDeviceFlag = true; + if (_last_discrepancy == 0) + _last_device_flag = true; search_result = true; } @@ -865,9 +593,9 @@ // if no device found then reset counters so next 'search' will be like a first if (!search_result || (romId.familyCode() == 0)) { - m_lastDiscrepancy = 0; - m_lastDeviceFlag = false; - m_lastFamilyDiscrepancy = 0; + _last_discrepancy = 0; + _last_device_flag = false; + _last_family_discrepancy = 0; search_result = false; } @@ -875,21 +603,6 @@ } //-------------------------------------------------------------------------- -// Find the 'first' devices on the 1-Wire network -// Return true : device found, ROM number in ROM_NO buffer -// false : no device present -// -OneWireMaster::CmdResult DS2465::OWFirst(RomId & romId) -{ - // reset the search state - m_lastDiscrepancy = 0; - m_lastDeviceFlag = false; - m_lastFamilyDiscrepancy = 0; - - return OWSearch(romId); -} - -//-------------------------------------------------------------------------- // The 'OWReadBlock' receives a block of data from the // 1-Wire Net. The destination is the mac buffer (rx_mac=1) or // the scratchpad (rx_mac=0). The result is buffer is returned. @@ -900,61 +613,21 @@ // OneWireMaster::CmdResult DS2465::OWReadBlock(uint8_t *rx_buf, uint8_t rx_len) { - uint8_t status; - int poll_count = 0; - OneWireMaster::CmdResult result; - // 1-Wire Receive Block (Case A) // S AD,0 [A] ADDR_CMD_REG [A] 1WRF [A] PR [A] P // [] indicates from slave // PR indicates byte containing parameter - - m_I2C_interface.start(); - if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write(CMD_1WRF) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write((unsigned char)rx_len) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - m_I2C_interface.stop(); - status = STATUS_1WB; - - // loop checking 1WB bit for completion of 1-Wire operation - // abort if poll limit reached - while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT)) - { - result = ReadMemory(ADDR_STATUS_REG, &status, 1, false); - if (result != OneWireMaster::Success) - return result; - } - // check for failure due to poll limit reached - if (poll_count >= POLL_LIMIT) - { - // handle error - // ... - //Reset(); - return OneWireMaster::TimeoutError; - } + OneWireMaster::CmdResult result; + uint8_t command[2] = { CMD_1WRF, rx_len }; + + result = WriteMemory(ADDR_CMD_REG, command, 2); + if (result == OneWireMaster::Success) + result = PollBusy(); + if (result == OneWireMaster::Success) + result = ReadMemory(ADDR_SPAD, rx_buf, rx_len, false); - result = ReadMemory(ADDR_SPAD, rx_buf, rx_len, false); - - // read out the data - return result; + return result; } @@ -980,19 +653,12 @@ OneWireMaster::CmdResult DS2465::OWWriteBlock(bool tx_mac, const uint8_t *tran_buf, uint8_t tran_len) { OneWireMaster::CmdResult result; - uint8_t par, status; - int poll_count = 0; + uint8_t command[2] = { CMD_1WTB, (tx_mac ? 0xFF : tran_len) }; - // create parameter byte - if (tx_mac) - par = 0xFF; - else + if (!tx_mac) { - // scratchpad is source - par = tran_len; - // prefill scratchpad with required data - result = WriteScratchpad(ADDR_SPAD, tran_buf, tran_len); + result = WriteMemory(ADDR_SPAD, tran_buf, tran_len); if (result != OneWireMaster::Success) return result; } @@ -1001,50 +667,13 @@ // S AD,0 [A] ADDR_CMD_REG [A] 1WTB [A] PR [A] P // [] indicates from slave // PR indicates byte containing parameter + + result = WriteMemory(ADDR_CMD_REG, command, 2); + + if (result == OneWireMaster::Success) + result = PollBusy(); - m_I2C_interface.start(); - if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write(CMD_1WTB) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write(par) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - m_I2C_interface.stop(); - - // loop checking 1WB bit for completion of 1-Wire operation - // abort if poll limit reached - status = STATUS_1WB; - while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT)) - { - result = ReadMemory(ADDR_STATUS_REG, &status, 1, false); - if (result != OneWireMaster::Success) - return result; - } - - // check for failure due to poll limit reached - if (poll_count >= POLL_LIMIT) - { - // handle error - // ... - //Reset(); - return OneWireMaster::TimeoutError; - } - - return OneWireMaster::Success; + return result; } //-------------------------------------------------------------------------- @@ -1069,24 +698,6 @@ } //-------------------------------------------------------------------------- -// Send 8 bits of communication to the 1-Wire Net and return the -// result 8 bits read from the 1-Wire Net. The parameter 'sendbyte' -// least significant 8 bits are used and the least significant 8 bits -// of the result is the return byte. -// -// 'sendbyte' - 8 bits to send (least significant byte) -// -// Returns: 8 bits read from sendbyte -// -OneWireMaster::CmdResult DS2465::OWTouchByte(uint8_t & sendrecvbyte) -{ - OneWireMaster::CmdResult result = OWWriteByte(sendrecvbyte); - if (result == OneWireMaster::Success) - OWReadByte(sendrecvbyte); - return result; -} - -//-------------------------------------------------------------------------- // Send 8 bits of read communication to the 1-Wire Net and return the // result 8 bits read from the 1-Wire Net. // @@ -1094,80 +705,31 @@ // OneWireMaster::CmdResult DS2465::OWReadByte(uint8_t & recvbyte) { - uint8_t status; - int poll_count = 0; - - // 1-Wire Read Bytes (Case C) - // S AD,0 [A] ADDR_CMD_REG [A] 1WRB [A] Sr AD,1 [A] [Status] A [Status] A - // \--------/ - // Repeat until 1WB bit has changed to 0 - // Sr AD,0 [A] SRP [A] E1 [A] Sr AD,1 [A] DD A\ P - // - // [] indicates from slave - // DD data read - - m_I2C_interface.start(); - if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write(CMD_1WRB) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - m_I2C_interface.start(); - if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_READ)) != I2C_WRITE_OK) - return OneWireMaster::CommunicationWriteError; + OneWireMaster::CmdResult result; + uint8_t buf; - // loop checking 1WB bit for completion of 1-Wire operation - // abort if poll limit reached - status = STATUS_1WB; - while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT)) - { - status = m_I2C_interface.read(m_I2C_interface.ACK); - } - - // one last read with NACK - m_I2C_interface.read(m_I2C_interface.NoACK); - - // check for failure due to poll limit reached - if (poll_count >= POLL_LIMIT) - { - // handle error - // ... - //Reset(); - return OneWireMaster::TimeoutError; - } + // 1-Wire Read Bytes (Case C) + // S AD,0 [A] ADDR_CMD_REG [A] 1WRB [A] Sr AD,1 [A] [Status] A [Status] A + // \--------/ + // Repeat until 1WB bit has changed to 0 + // Sr AD,0 [A] SRP [A] E1 [A] Sr AD,1 [A] DD A\ P + // + // [] indicates from slave + // DD data read + + buf = CMD_1WRB; + result = WriteMemory(ADDR_CMD_REG, &buf, 1); - m_I2C_interface.start(); - if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write(ADDR_DATA_REG) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - m_I2C_interface.start(); - if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_READ)) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - recvbyte = m_I2C_interface.read(m_I2C_interface.NoACK); + if (result == OneWireMaster::Success) + result = PollBusy(); + + if (result == OneWireMaster::Success) + result = ReadMemory(ADDR_DATA_REG, &buf, 1); - m_I2C_interface.stop(); + if (result == OneWireMaster::Success) + recvbyte = buf; - return OneWireMaster::Success; + return result; } //-------------------------------------------------------------------------- @@ -1181,69 +743,22 @@ // false: echo was not the same // OneWireMaster::CmdResult DS2465::OWWriteByte(uint8_t sendbyte) -{ - uint8_t status; - int poll_count = 0; - +{ // 1-Wire Write Byte (Case B) // S AD,0 [A] ADDR_CMD_REG [A] 1WWB [A] DD [A] Sr AD,1 [A] [Status] A [Status] A\ P // \--------/ // Repeat until 1WB bit has changed to 0 // [] indicates from slave // DD data to write - - m_I2C_interface.start(); - if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write(CMD_1WWB) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write(sendbyte) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } + + OneWireMaster::CmdResult result; + uint8_t command[2] = { CMD_1WWB, sendbyte }; + + result = WriteMemory(ADDR_CMD_REG, command, 2); + if (result == OneWireMaster::Success) + result = PollBusy(); - m_I2C_interface.start(); - if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_READ)) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - - // loop checking 1WB bit for completion of 1-Wire operation - // abort if poll limit reached - status = STATUS_1WB; - while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT)) - { - status = m_I2C_interface.read(m_I2C_interface.ACK); - } - - // one last read with NACK - m_I2C_interface.read(m_I2C_interface.NoACK); - - m_I2C_interface.stop(); - - // check for failure due to poll limit reached - if (poll_count >= POLL_LIMIT) - { - // handle error - // ... - //Reset(); - return OneWireMaster::TimeoutError; - } - - return OneWireMaster::Success; + return result; } //-------------------------------------------------------------------------- @@ -1259,168 +774,26 @@ // OneWireMaster::CmdResult DS2465::OWTouchBit(uint8_t & sendrecvbit) { - unsigned char status; - int poll_count = 0; - // 1-Wire bit (Case B) // S AD,0 [A] ADDR_CMD_REG [A] 1WSB [A] BB [A] Sr AD,1 [A] [Status] A [Status] A\ P // \--------/ // Repeat until 1WB bit has changed to 0 // [] indicates from slave // BB indicates byte containing bit value in msbit - - m_I2C_interface.start(); - if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write(CMD_1WSB) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write(sendrecvbit ? 0x80 : 0x00) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - m_I2C_interface.start(); - if (m_I2C_interface.write(m_I2C_address | I2C_READ) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - // loop checking 1WB bit for completion of 1-Wire operation - // abort if poll limit reached - status = STATUS_1WB; - while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT)) - { - status = m_I2C_interface.read(status & STATUS_1WB); - } - - // one last read with NACK - m_I2C_interface.read(m_I2C_interface.NoACK); - - m_I2C_interface.stop(); - - // check for failure due to poll limit reached - if (poll_count >= POLL_LIMIT) - { - // handle error - // ... - //Reset(); - return OneWireMaster::TimeoutError; - } - - // check bit state - sendrecvbit = (status & STATUS_SBR); + OneWireMaster::CmdResult result; + uint8_t command[2] = { CMD_1WSB, (sendrecvbit ? 0x80 : 0x00) }; + uint8_t status; + + result = WriteMemory(ADDR_CMD_REG, command, 2); - return OneWireMaster::Success; -} - -//-------------------------------------------------------------------------- -// Reads 1 bit of communication from the 1-Wire Net and returns the -// result -// -// Returns: 1 bit read from 1-Wire Net -// -OneWireMaster::CmdResult DS2465::OWReadBit(uint8_t & recvbit) -{ - recvbit = 0x01; - return OWTouchBit(recvbit); -} - -//-------------------------------------------------------------------------- -// Send 1 bit of communication to the 1-Wire Net. -// The parameter 'sendbit' least significant bit is used. -// -// 'sendbit' - 1 bit to send (least significant byte) -// -OneWireMaster::CmdResult DS2465::OWWriteBit(uint8_t sendbit) -{ - return OWTouchBit(sendbit); -} - -//-------------------------------------------------------------------------- -// -// -// -// -// -// -// -// Returns: -// -// -OneWireMaster::CmdResult DS2465::Write_Command_Reg(unsigned char cmd, unsigned char par, bool poll) const -{ - int poll_count = 0, status; + if (result == OneWireMaster::Success) + result = PollBusy(&status); - // Generic command - // S AD,0 [A] ADDR_CMD_REG [A] CMD [A] PP [A] P - // [] indicates from slave - // CMD command - // PP parameter - - m_I2C_interface.start(); - if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write(cmd) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write(par) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - - m_I2C_interface.stop(); - - poll_count = 0; - if (poll) - { - // Poll for completion by checking for NAK on address - do - { - m_I2C_interface.start(); - status = m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)); - m_I2C_interface.stop(); - } while ((status != I2C_WRITE_OK) && (poll_count++ < POLL_LIMIT)); - } - else - { - // delay instead of poll, longest operation (only for SHA compute) - wait_ms(SHA_COMPUTATION_DELAY * 2); - wait_ms(8); // Additional delay - } - - // check for failure due to poll limit reached - if (poll_count >= POLL_LIMIT) - { - // handle error - // ... - //Reset(); - return OneWireMaster::TimeoutError; - } - - return OneWireMaster::Success; + if (result == OneWireMaster::Success) + sendrecvbit = (status & STATUS_SBR); + + return result; } //-------------------------------------------------------------------------- @@ -1433,7 +806,7 @@ // Returns: true write successful // false failure to complete write // -OneWireMaster::CmdResult DS2465::WriteScratchpad(std::uint8_t addr, const std::uint8_t * buf, size_t bufLen) const +OneWireMaster::CmdResult DS2465::CWriteMemory(std::uint8_t addr, const std::uint8_t * buf, size_t bufLen) const { int i; @@ -1524,32 +897,6 @@ return OneWireMaster::Success; } - - - - -OneWireMaster::CmdResult DS2465::ReadOneWireConfig(OWConfigAddr addr, std::uint8_t & config) const -{ - std::uint8_t buf; - OneWireMaster::CmdResult result = ReadMemory(addr, &buf, 1, false); - if (result == OneWireMaster::Success) - config = buf; - return result; -} - - - - - -OneWireMaster::CmdResult DS2465::WriteOneWireConfig(OWConfigAddr addr, unsigned int ovr, unsigned int std) -{ - std::uint8_t buf; - - // convert and write value - buf = (ovr << 4) | std; - return (WriteScratchpad(addr, &buf, 1)); -} - //-------------------------------------------------------------------------- // Write the configuration register in the DS2465. The configuration // options are provided in the lower nibble of the provided config byte. @@ -1558,68 +905,51 @@ // Returns: true: config written and response correct // false: response incorrect // -OneWireMaster::CmdResult DS2465::Write_Config(uint8_t config) +OneWireMaster::CmdResult DS2465::WriteConfig(const Config & config) { - unsigned char read_config; + std::uint8_t configBuf; + OneWireMaster::CmdResult result; - // Write configuration byte - // S AD,0 [A] ADDR_WCFG_REG [A] CONIG [A] P - // [] indicates from slave - // CF configuration byte to write - - m_I2C_interface.start(); - - if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write(ADDR_WCFG_REG) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write((unsigned char)(config | (~config << 4))) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - m_I2C_interface.stop(); - - // read it back to confirm - // S AD,0 [A] ADDR_WCFG_REG [A] Sr AD,1 [A] [CF] A - - m_I2C_interface.start(); - if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write(ADDR_WCFG_REG) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - m_I2C_interface.start(); - if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_READ)) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - read_config = m_I2C_interface.read(m_I2C_interface.NoACK); - m_I2C_interface.stop(); - - - // check for failure due to incorrect read back - if (config != read_config) + configBuf = config.writeByte(); + result = WriteMemory(ADDR_WCFG_REG, &configBuf, 1); + if (result == OneWireMaster::Success) { - // handle error - // ... - //Reset(); - - return OneWireMaster::TimeoutError; + result = ReadMemory(ADDR_WCFG_REG, &configBuf, 1); + } + if (result == OneWireMaster::Success) + { + if (configBuf != config.readByte()) + result = OneWireMaster::OperationFailure; } + return result; +} + + + + +OneWireMaster::CmdResult DS2465::PollBusy(uint8_t * pStatus) +{ + const unsigned int pollLimit = 200; + + OneWireMaster::CmdResult result; + uint8_t status; + unsigned int pollCount = 0; + + // loop checking 1WB bit for completion of 1-Wire operation + // abort if poll limit reached + + do + { + result = ReadMemory(ADDR_STATUS_REG, &status, 1, true); + if (result != OneWireMaster::Success) + return result; + if (pStatus != NULL) + *pStatus = status; + if (pollCount++ >= pollLimit) + return OneWireMaster::TimeoutError; + } while (status & STATUS_1WB); + return OneWireMaster::Success; } @@ -1630,122 +960,58 @@ // false(0): no presense pulses detected // OneWireMaster::CmdResult DS2465::OWReset(void) -{ - unsigned char status; - int poll_count = 0; - - // 1-Wire reset (Case B) - // S AD,0 [A] ADDR_CMD_REG [A] 1WRS [A] Sr AD,1 [A] [Status] A [Status] A\ P - // \--------/ - // Repeat until 1WB bit has changed to 0 - // [] indicates from slave +{ + // 1-Wire reset (Case B) + // S AD,0 [A] ADDR_CMD_REG [A] 1WRS [A] Sr AD,1 [A] [Status] A [Status] A\ P + // \--------/ + // Repeat until 1WB bit has changed to 0 + // [] indicates from slave - m_I2C_interface.start(); + OneWireMaster::CmdResult result; + uint8_t buf; - if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - if (m_I2C_interface.write(CMD_1WRS) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - m_I2C_interface.start(); - if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_READ)) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } + buf = CMD_1WRS; + result = WriteMemory(ADDR_CMD_REG, &buf, 1); - // loop checking 1WB bit for completion of 1-Wire operation - // abort if poll limit reached - status = STATUS_1WB; - while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT)) - { - status = m_I2C_interface.read(m_I2C_interface.ACK); - } - - // one last read with NACK - m_I2C_interface.read(m_I2C_interface.NoACK); - - m_I2C_interface.stop(); + if (result == OneWireMaster::Success) + result = PollBusy(&buf); + + if (result == OneWireMaster::Success) + { + // check for presence detect + if ((buf & STATUS_PPD) != STATUS_PPD) + result = OneWireMaster::OperationFailure; + } - // check for failure due to poll limit reached - if (poll_count >= POLL_LIMIT) - { - // handle error - // ... - //Reset(); - return OneWireMaster::TimeoutError; - } - - // check for short condition - if (status & STATUS_SD) - short_detected = true; - else - short_detected = false; - - - // check for presence detect - if (status & STATUS_PPD) - return OneWireMaster::Success; - // else - return OneWireMaster::OperationFailure; + return result; } OneWireMaster::CmdResult DS2465::Reset(void) -{ - uint8_t status; - +{ // Device Reset // S AD,0 [A] ADDR_CMD_REG [A] 1WMR [A] Sr AD,1 [A] [SS] A\ P // [] indicates from slave // SS status byte to read to verify state - m_I2C_interface.start(); + OneWireMaster::CmdResult result; + uint8_t buf; - if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } + buf = CMD_1WMR; + result = WriteMemory(ADDR_CMD_REG, &buf, 1); - if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK) + if (result == OneWireMaster::Success) + result = ReadMemory(ADDR_STATUS_REG, &buf, 1, true); + + if (result == OneWireMaster::Success) { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - - if (m_I2C_interface.write(CMD_1WMR) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; + if ((buf & 0xF7) != 0x10) + result = OneWireMaster::OperationFailure; } - - m_I2C_interface.start(); - - if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_READ)) != I2C_WRITE_OK) - { - m_I2C_interface.stop(); - return OneWireMaster::CommunicationWriteError; - } - - status = m_I2C_interface.read(m_I2C_interface.NoACK); + + if (result == OneWireMaster::Success) + OWReset(); // do a command to get 1-Wire master reset out of holding state - m_I2C_interface.stop(); - - // do a command to get 1-Wire master reset out of holding state - OWReset(); - - // check for failure due to incorrect read back of status - return ((status & 0xF7) == 0x10) ? OneWireMaster::Success : OneWireMaster::OperationFailure; + return result; } OneWireMaster::CmdResult DS2465::Detect(void) @@ -1758,12 +1024,9 @@ return result; // default configuration - c1WS = 0; - cSPU = 0; - cPDN = 0; - cAPU = CONFIG_APU; + m_curConfig.reset(); // write the default configuration setup - result = Write_Config(c1WS | cSPU | cPDN | cAPU); + result = WriteConfig(m_curConfig); return result; }