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.

Committer:
IanBenzMaxim
Date:
Thu Mar 31 11:56:01 2016 -0500
Revision:
33:a4c015046956
Parent:
32:bce180b544ed
Child:
34:11fffbe98ef9
Created a generic array wrapper class. Updated array types used in ISha256MacCoprocessor and DS28E15_22_25 for clarity.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
IanBenzMaxim 21:00c94aeb533e 1 #include "DS2465.hpp"
IanBenzMaxim 27:d5aaefa252f1 2 #include "RomId.hpp"
IanBenzMaxim 27:d5aaefa252f1 3 #include "mbed.h"
IanBenzMaxim 21:00c94aeb533e 4
IanBenzMaxim 21:00c94aeb533e 5 #define I2C_WRITE 0
IanBenzMaxim 21:00c94aeb533e 6 #define I2C_READ 1
IanBenzMaxim 21:00c94aeb533e 7
IanBenzMaxim 21:00c94aeb533e 8 // DS2465 commands
IanBenzMaxim 21:00c94aeb533e 9 #define CMD_1WMR 0xF0
IanBenzMaxim 21:00c94aeb533e 10 #define CMD_WCFG 0xD2
IanBenzMaxim 21:00c94aeb533e 11 #define CMD_CHSL 0xC3
IanBenzMaxim 21:00c94aeb533e 12 #define CMD_SRP 0xE1
IanBenzMaxim 21:00c94aeb533e 13
IanBenzMaxim 21:00c94aeb533e 14 #define CMD_1WRS 0xB4
IanBenzMaxim 21:00c94aeb533e 15 #define CMD_1WWB 0xA5
IanBenzMaxim 21:00c94aeb533e 16 #define CMD_1WRB 0x96
IanBenzMaxim 21:00c94aeb533e 17 #define CMD_1WSB 0x87
IanBenzMaxim 21:00c94aeb533e 18 #define CMD_1WT 0x78
IanBenzMaxim 21:00c94aeb533e 19 #define CMD_1WTB 0x69
IanBenzMaxim 21:00c94aeb533e 20 #define CMD_1WRF 0xE1
IanBenzMaxim 21:00c94aeb533e 21 #define CMD_CPS 0x5A
IanBenzMaxim 21:00c94aeb533e 22 #define CMD_CSS 0x4B
IanBenzMaxim 21:00c94aeb533e 23 #define CMD_CSAM 0x3C
IanBenzMaxim 21:00c94aeb533e 24 #define CMD_CSWM 0x2D
IanBenzMaxim 21:00c94aeb533e 25 #define CMD_CNMS 0x1E
IanBenzMaxim 21:00c94aeb533e 26 #define CMD_SPR 0x0F
IanBenzMaxim 21:00c94aeb533e 27
IanBenzMaxim 21:00c94aeb533e 28 // DS2465 status bits
IanBenzMaxim 21:00c94aeb533e 29 #define STATUS_1WB 0x01
IanBenzMaxim 21:00c94aeb533e 30 #define STATUS_PPD 0x02
IanBenzMaxim 21:00c94aeb533e 31 #define STATUS_SD 0x04
IanBenzMaxim 21:00c94aeb533e 32 #define STATUS_LL 0x08
IanBenzMaxim 21:00c94aeb533e 33 #define STATUS_RST 0x10
IanBenzMaxim 21:00c94aeb533e 34 #define STATUS_SBR 0x20
IanBenzMaxim 21:00c94aeb533e 35 #define STATUS_TSB 0x40
IanBenzMaxim 21:00c94aeb533e 36 #define STATUS_DIR 0x80
IanBenzMaxim 21:00c94aeb533e 37
IanBenzMaxim 21:00c94aeb533e 38 // delays (if not polling for complete)
IanBenzMaxim 21:00c94aeb533e 39 #define EEPROM_WRITE_DELAY 30
IanBenzMaxim 21:00c94aeb533e 40 #define LOAD_SECRET_DELAY 90
IanBenzMaxim 21:00c94aeb533e 41 #define SHA_COMPUTATION_DELAY 5
IanBenzMaxim 21:00c94aeb533e 42
IanBenzMaxim 21:00c94aeb533e 43 static const int I2C_WRITE_OK = 0;
IanBenzMaxim 21:00c94aeb533e 44
IanBenzMaxim 24:8942d8478d68 45
IanBenzMaxim 24:8942d8478d68 46 std::uint8_t DS2465::Config::readByte() const
IanBenzMaxim 24:8942d8478d68 47 {
IanBenzMaxim 24:8942d8478d68 48 std::uint8_t config = 0;
IanBenzMaxim 24:8942d8478d68 49 if (c1WS)
IanBenzMaxim 24:8942d8478d68 50 config |= 0x08;
IanBenzMaxim 24:8942d8478d68 51 if (cSPU)
IanBenzMaxim 24:8942d8478d68 52 config |= 0x04;
IanBenzMaxim 24:8942d8478d68 53 if (cPDN)
IanBenzMaxim 24:8942d8478d68 54 config |= 0x02;
IanBenzMaxim 24:8942d8478d68 55 if (cAPU)
IanBenzMaxim 24:8942d8478d68 56 config |= 0x01;
IanBenzMaxim 24:8942d8478d68 57 return config;
IanBenzMaxim 24:8942d8478d68 58 }
IanBenzMaxim 24:8942d8478d68 59
IanBenzMaxim 24:8942d8478d68 60 std::uint8_t DS2465::Config::writeByte() const
IanBenzMaxim 24:8942d8478d68 61 {
IanBenzMaxim 24:8942d8478d68 62 std::uint8_t config = readByte();
IanBenzMaxim 24:8942d8478d68 63 return ((~config << 4) | config);
IanBenzMaxim 24:8942d8478d68 64 }
IanBenzMaxim 24:8942d8478d68 65
IanBenzMaxim 24:8942d8478d68 66 void DS2465::Config::reset()
IanBenzMaxim 24:8942d8478d68 67 {
IanBenzMaxim 24:8942d8478d68 68 c1WS = cSPU = cPDN = false;
IanBenzMaxim 24:8942d8478d68 69 cAPU = true;
IanBenzMaxim 24:8942d8478d68 70 }
IanBenzMaxim 24:8942d8478d68 71
IanBenzMaxim 24:8942d8478d68 72
IanBenzMaxim 24:8942d8478d68 73
IanBenzMaxim 24:8942d8478d68 74
IanBenzMaxim 32:bce180b544ed 75 DS2465::DS2465(I2C & I2C_interface, std::uint8_t I2C_address)
IanBenzMaxim 21:00c94aeb533e 76 : m_I2C_interface(I2C_interface), m_I2C_address(I2C_address)
IanBenzMaxim 21:00c94aeb533e 77 {
IanBenzMaxim 21:00c94aeb533e 78
IanBenzMaxim 21:00c94aeb533e 79 }
IanBenzMaxim 21:00c94aeb533e 80
IanBenzMaxim 21:00c94aeb533e 81
IanBenzMaxim 21:00c94aeb533e 82
IanBenzMaxim 21:00c94aeb533e 83
IanBenzMaxim 21:00c94aeb533e 84 OneWireMaster::CmdResult DS2465::OWInitMaster()
IanBenzMaxim 21:00c94aeb533e 85 {
IanBenzMaxim 21:00c94aeb533e 86 return Detect();
IanBenzMaxim 21:00c94aeb533e 87 }
IanBenzMaxim 21:00c94aeb533e 88
IanBenzMaxim 21:00c94aeb533e 89
IanBenzMaxim 21:00c94aeb533e 90 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 91 // Compute Next Master Secret DS2465
IanBenzMaxim 21:00c94aeb533e 92 //
IanBenzMaxim 21:00c94aeb533e 93 // 'swap' - 1 if swapping a page into the computation
IanBenzMaxim 21:00c94aeb533e 94 // 'page' - page number to swap in
IanBenzMaxim 21:00c94aeb533e 95 // 'region' - (1) first 1/2 page, (2) second 1/2 page, (3) entire page
IanBenzMaxim 21:00c94aeb533e 96 //
IanBenzMaxim 21:00c94aeb533e 97 // Returns: true write successful
IanBenzMaxim 21:00c94aeb533e 98 // false failure to complete read
IanBenzMaxim 21:00c94aeb533e 99 //
IanBenzMaxim 33:a4c015046956 100 OneWireMaster::CmdResult DS2465::computeNextMasterSecret(bool swap, unsigned int pageNum, PageRegion region)
IanBenzMaxim 21:00c94aeb533e 101 {
IanBenzMaxim 27:d5aaefa252f1 102 std::uint8_t command[2] = { CMD_CNMS, (swap ? (0xC8 | (pageNum << 4) | region) : 0xBF) };
IanBenzMaxim 24:8942d8478d68 103 return WriteMemory(ADDR_CMD_REG, command, 2);
IanBenzMaxim 21:00c94aeb533e 104 }
IanBenzMaxim 21:00c94aeb533e 105
IanBenzMaxim 21:00c94aeb533e 106 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 107 // Compute Write MAC DS2465
IanBenzMaxim 21:00c94aeb533e 108 //
IanBenzMaxim 21:00c94aeb533e 109 // 'regwrite' - true if writing to a register, false if regular memory
IanBenzMaxim 21:00c94aeb533e 110 // 'swap' - true if swapping a page into the computation
IanBenzMaxim 21:00c94aeb533e 111 // 'page' - page number to swap in
IanBenzMaxim 21:00c94aeb533e 112 // 'segment' - segment number if swaping
IanBenzMaxim 21:00c94aeb533e 113 //
IanBenzMaxim 21:00c94aeb533e 114 // Returns: true write successful
IanBenzMaxim 21:00c94aeb533e 115 // false failure to complete read
IanBenzMaxim 21:00c94aeb533e 116 //
IanBenzMaxim 33:a4c015046956 117 OneWireMaster::CmdResult DS2465::computeWriteMac(bool regwrite, bool swap, unsigned int pageNum, unsigned int segmentNum) const
IanBenzMaxim 21:00c94aeb533e 118 {
IanBenzMaxim 27:d5aaefa252f1 119 std::uint8_t command[2] = { CMD_CSWM, ((regwrite << 7) | (swap << 6) | (pageNum << 4) | segmentNum) };
IanBenzMaxim 24:8942d8478d68 120 return CWriteMemory(ADDR_CMD_REG, command, 2);
IanBenzMaxim 21:00c94aeb533e 121 }
IanBenzMaxim 21:00c94aeb533e 122
IanBenzMaxim 21:00c94aeb533e 123 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 124 // Compute Slave Authentication MAC DS2465
IanBenzMaxim 21:00c94aeb533e 125 //
IanBenzMaxim 21:00c94aeb533e 126 // 'swap' - true if swapping a page into the computation
IanBenzMaxim 21:00c94aeb533e 127 // 'page' - page number to swap in
IanBenzMaxim 21:00c94aeb533e 128 // 'region' - (1) first 1/2 page, (2) second 1/2 page, (3) entire page
IanBenzMaxim 21:00c94aeb533e 129 //
IanBenzMaxim 21:00c94aeb533e 130 // Returns: true write successful
IanBenzMaxim 21:00c94aeb533e 131 // false failure to complete read
IanBenzMaxim 21:00c94aeb533e 132 //
IanBenzMaxim 33:a4c015046956 133 OneWireMaster::CmdResult DS2465::computeAuthMac(bool swap, unsigned int pageNum, PageRegion region) const
IanBenzMaxim 21:00c94aeb533e 134 {
IanBenzMaxim 27:d5aaefa252f1 135 std::uint8_t command[2] = { CMD_CSAM, (swap ? (0xC8 | (pageNum << 4) | region) : 0xBF) };
IanBenzMaxim 24:8942d8478d68 136 return CWriteMemory(ADDR_CMD_REG, command, 2);
IanBenzMaxim 21:00c94aeb533e 137 }
IanBenzMaxim 21:00c94aeb533e 138
IanBenzMaxim 21:00c94aeb533e 139 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 140 // Compute S-Secret on DS2465
IanBenzMaxim 21:00c94aeb533e 141 //
IanBenzMaxim 21:00c94aeb533e 142 // 'swap' - true if swapping a page into the computation
IanBenzMaxim 21:00c94aeb533e 143 // 'page' - page number to swap in
IanBenzMaxim 21:00c94aeb533e 144 // 'region' - (1) first 1/2 page, (2) second 1/2 page, (3) entire page
IanBenzMaxim 21:00c94aeb533e 145 //
IanBenzMaxim 21:00c94aeb533e 146 // Returns: true write successful
IanBenzMaxim 21:00c94aeb533e 147 // false failure to complete read
IanBenzMaxim 21:00c94aeb533e 148 //
IanBenzMaxim 33:a4c015046956 149 OneWireMaster::CmdResult DS2465::computeSlaveSecret(bool swap, unsigned int pageNum, PageRegion region)
IanBenzMaxim 21:00c94aeb533e 150 {
IanBenzMaxim 27:d5aaefa252f1 151 std::uint8_t command[2] = { CMD_CSS, (swap ? (0xC8 | (pageNum << 4) | region) : 0xBF) };
IanBenzMaxim 24:8942d8478d68 152 return WriteMemory(ADDR_CMD_REG, command, 2);
IanBenzMaxim 21:00c94aeb533e 153 }
IanBenzMaxim 21:00c94aeb533e 154
IanBenzMaxim 21:00c94aeb533e 155
IanBenzMaxim 21:00c94aeb533e 156
IanBenzMaxim 21:00c94aeb533e 157
IanBenzMaxim 33:a4c015046956 158 ISha256MacCoprocessor::CmdResult DS2465::setMasterSecret(const Secret & secret)
IanBenzMaxim 21:00c94aeb533e 159 {
IanBenzMaxim 21:00c94aeb533e 160 OneWireMaster::CmdResult result;
IanBenzMaxim 33:a4c015046956 161 result = WriteMemory(ADDR_SPAD, secret, secret.length);
IanBenzMaxim 21:00c94aeb533e 162 if (result == OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 163 result = CopyScratchpad(1, 0, 1, 0);
IanBenzMaxim 21:00c94aeb533e 164 if (result == OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 165 wait_ms(8 * EEPROM_WRITE_DELAY);
IanBenzMaxim 21:00c94aeb533e 166 return (result == OneWireMaster::Success ? ISha256MacCoprocessor::Success : ISha256MacCoprocessor::OperationFailure);
IanBenzMaxim 21:00c94aeb533e 167 }
IanBenzMaxim 21:00c94aeb533e 168
IanBenzMaxim 33:a4c015046956 169 ISha256MacCoprocessor::CmdResult DS2465::computeWriteMac(const WriteMacData & writeMacData, Mac & mac) const
IanBenzMaxim 21:00c94aeb533e 170 {
IanBenzMaxim 21:00c94aeb533e 171 OneWireMaster::CmdResult result;
IanBenzMaxim 21:00c94aeb533e 172 // Write input data to scratchpad
IanBenzMaxim 33:a4c015046956 173 result = WriteScratchpad(writeMacData, writeMacData.length);
IanBenzMaxim 21:00c94aeb533e 174 // Compute MAC
IanBenzMaxim 21:00c94aeb533e 175 if (result == OneWireMaster::Success)
IanBenzMaxim 33:a4c015046956 176 result = computeWriteMac(false, false, 0, 0);
IanBenzMaxim 21:00c94aeb533e 177 if (result == OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 178 {
IanBenzMaxim 21:00c94aeb533e 179 wait_ms(SHA_COMPUTATION_DELAY);
IanBenzMaxim 21:00c94aeb533e 180 // Read MAC from register
IanBenzMaxim 33:a4c015046956 181 result = ReadMemory(ADDR_MAC_READ, mac, mac.length, true);
IanBenzMaxim 21:00c94aeb533e 182 }
IanBenzMaxim 21:00c94aeb533e 183 return (result == OneWireMaster::Success ? ISha256MacCoprocessor::Success : ISha256MacCoprocessor::OperationFailure);
IanBenzMaxim 21:00c94aeb533e 184 }
IanBenzMaxim 21:00c94aeb533e 185
IanBenzMaxim 33:a4c015046956 186 ISha256MacCoprocessor::CmdResult DS2465::computeAuthMac(const DevicePage & devicePage, const DeviceScratchpad & challenge, const AuthMacData & authMacData, Mac & mac) const
IanBenzMaxim 21:00c94aeb533e 187 {
IanBenzMaxim 21:00c94aeb533e 188 OneWireMaster::CmdResult result;
IanBenzMaxim 21:00c94aeb533e 189 int addr = ADDR_SPAD;
IanBenzMaxim 21:00c94aeb533e 190 // Write input data to scratchpad
IanBenzMaxim 33:a4c015046956 191 result = CWriteMemory(addr, devicePage, devicePage.length);
IanBenzMaxim 21:00c94aeb533e 192 if (result == OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 193 {
IanBenzMaxim 33:a4c015046956 194 addr += devicePage.length;
IanBenzMaxim 33:a4c015046956 195 result = CWriteMemory(addr, challenge, challenge.length);
IanBenzMaxim 21:00c94aeb533e 196 }
IanBenzMaxim 21:00c94aeb533e 197 if (result == OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 198 {
IanBenzMaxim 33:a4c015046956 199 addr += challenge.length;
IanBenzMaxim 33:a4c015046956 200 result = CWriteMemory(addr, authMacData, authMacData.length);
IanBenzMaxim 21:00c94aeb533e 201 }
IanBenzMaxim 21:00c94aeb533e 202 // Compute MAC
IanBenzMaxim 21:00c94aeb533e 203 if (result == OneWireMaster::Success)
IanBenzMaxim 33:a4c015046956 204 result = computeAuthMac(false, 0, REGION_FULL_PAGE);
IanBenzMaxim 21:00c94aeb533e 205 if (result == OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 206 {
IanBenzMaxim 21:00c94aeb533e 207 wait_ms(SHA_COMPUTATION_DELAY * 2);
IanBenzMaxim 21:00c94aeb533e 208 // Read MAC from register
IanBenzMaxim 33:a4c015046956 209 result = ReadMemory(ADDR_MAC_READ, mac, mac.length, true);
IanBenzMaxim 21:00c94aeb533e 210 }
IanBenzMaxim 21:00c94aeb533e 211 return (result == OneWireMaster::Success ? ISha256MacCoprocessor::Success : ISha256MacCoprocessor::OperationFailure);
IanBenzMaxim 21:00c94aeb533e 212 }
IanBenzMaxim 21:00c94aeb533e 213
IanBenzMaxim 33:a4c015046956 214 ISha256MacCoprocessor::CmdResult DS2465::computeSlaveSecret(const DevicePage & devicePage, const DeviceScratchpad & deviceScratchpad, const SlaveSecretData & slaveSecretData)
IanBenzMaxim 21:00c94aeb533e 215 {
IanBenzMaxim 21:00c94aeb533e 216 OneWireMaster::CmdResult result;
IanBenzMaxim 21:00c94aeb533e 217 int addr = ADDR_SPAD;
IanBenzMaxim 21:00c94aeb533e 218 // Write input data to scratchpad
IanBenzMaxim 33:a4c015046956 219 result = WriteMemory(addr, devicePage, devicePage.length);
IanBenzMaxim 21:00c94aeb533e 220 if (result == OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 221 {
IanBenzMaxim 33:a4c015046956 222 addr += devicePage.length;
IanBenzMaxim 33:a4c015046956 223 result = WriteMemory(addr, deviceScratchpad, deviceScratchpad.length);
IanBenzMaxim 21:00c94aeb533e 224 }
IanBenzMaxim 21:00c94aeb533e 225 if (result == OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 226 {
IanBenzMaxim 33:a4c015046956 227 addr += deviceScratchpad.length;
IanBenzMaxim 33:a4c015046956 228 result = WriteMemory(addr, slaveSecretData, slaveSecretData.length);
IanBenzMaxim 21:00c94aeb533e 229 }
IanBenzMaxim 21:00c94aeb533e 230 // Compute secret
IanBenzMaxim 21:00c94aeb533e 231 if (result == OneWireMaster::Success)
IanBenzMaxim 33:a4c015046956 232 result = computeSlaveSecret(false, 0, REGION_FULL_PAGE);
IanBenzMaxim 21:00c94aeb533e 233 if (result == OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 234 wait_ms(SHA_COMPUTATION_DELAY * 2);
IanBenzMaxim 21:00c94aeb533e 235 return (result == OneWireMaster::Success ? ISha256MacCoprocessor::Success : ISha256MacCoprocessor::OperationFailure);
IanBenzMaxim 21:00c94aeb533e 236 }
IanBenzMaxim 21:00c94aeb533e 237
IanBenzMaxim 21:00c94aeb533e 238 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 239 // Copy Scratchpad on DS2465 to either secret or memory page
IanBenzMaxim 21:00c94aeb533e 240 //
IanBenzMaxim 21:00c94aeb533e 241 // 'dest_secret' - 1 if destination is secret, 0 if memory page
IanBenzMaxim 21:00c94aeb533e 242 // 'page' - page number if dest_secret=0
IanBenzMaxim 21:00c94aeb533e 243 // 'notfull' - 0 if only 4 byte segment, 1 if writing to full page,
IanBenzMaxim 21:00c94aeb533e 244 // 'seg' - Segment number if full=0.
IanBenzMaxim 21:00c94aeb533e 245 //
IanBenzMaxim 21:00c94aeb533e 246 // Returns: true write successful
IanBenzMaxim 21:00c94aeb533e 247 // false failure to complete read
IanBenzMaxim 21:00c94aeb533e 248 //
IanBenzMaxim 21:00c94aeb533e 249 OneWireMaster::CmdResult DS2465::CopyScratchpad(bool dest_secret, unsigned int pageNum, bool notFull, unsigned int segmentNum)
IanBenzMaxim 21:00c94aeb533e 250 {
IanBenzMaxim 27:d5aaefa252f1 251 std::uint8_t command[2] = { CMD_CPS, (dest_secret ? 0 : (0x80 | (pageNum << 4) | (notFull << 3) | segmentNum)) };
IanBenzMaxim 24:8942d8478d68 252 return WriteMemory(ADDR_CMD_REG, command, 2);
IanBenzMaxim 21:00c94aeb533e 253 }
IanBenzMaxim 21:00c94aeb533e 254
IanBenzMaxim 26:a361e3f42ba5 255
IanBenzMaxim 21:00c94aeb533e 256
IanBenzMaxim 26:a361e3f42ba5 257
IanBenzMaxim 32:bce180b544ed 258 OneWireMaster::CmdResult DS2465::ConfigureLevel(OWLevel level)
IanBenzMaxim 26:a361e3f42ba5 259 {
IanBenzMaxim 26:a361e3f42ba5 260 OneWireMaster::CmdResult result;
IanBenzMaxim 32:bce180b544ed 261 if (m_curConfig.cSPU != (level == LEVEL_STRONG))
IanBenzMaxim 26:a361e3f42ba5 262 {
IanBenzMaxim 32:bce180b544ed 263 m_curConfig.cSPU = (level == LEVEL_STRONG);
IanBenzMaxim 32:bce180b544ed 264 result = WriteConfig(m_curConfig);
IanBenzMaxim 21:00c94aeb533e 265 }
IanBenzMaxim 26:a361e3f42ba5 266 else
IanBenzMaxim 26:a361e3f42ba5 267 {
IanBenzMaxim 26:a361e3f42ba5 268 result = OneWireMaster::Success;
IanBenzMaxim 26:a361e3f42ba5 269 }
IanBenzMaxim 21:00c94aeb533e 270 return result;
IanBenzMaxim 21:00c94aeb533e 271 }
IanBenzMaxim 21:00c94aeb533e 272
IanBenzMaxim 21:00c94aeb533e 273 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 274 // Set the 1-Wire Net line level pull-up to normal. The DS2465 does only
IanBenzMaxim 21:00c94aeb533e 275 // allows enabling strong pull-up on a bit or byte event. Consequently this
IanBenzMaxim 21:00c94aeb533e 276 // function only allows the MODE_STANDARD argument. To enable strong pull-up
IanBenzMaxim 21:00c94aeb533e 277 // use OWWriteBytePower or OWReadBitPower.
IanBenzMaxim 21:00c94aeb533e 278 //
IanBenzMaxim 21:00c94aeb533e 279 // 'new_level' - new level defined as
IanBenzMaxim 21:00c94aeb533e 280 // MODE_STANDARD 0x00
IanBenzMaxim 21:00c94aeb533e 281 //
IanBenzMaxim 21:00c94aeb533e 282 // Returns: current 1-Wire Net level
IanBenzMaxim 21:00c94aeb533e 283 //
IanBenzMaxim 32:bce180b544ed 284 OneWireMaster::CmdResult DS2465::OWSetLevel(OWLevel new_level)
IanBenzMaxim 21:00c94aeb533e 285 {
IanBenzMaxim 32:bce180b544ed 286 if (new_level == LEVEL_STRONG)
IanBenzMaxim 27:d5aaefa252f1 287 return OneWireMaster::OperationFailure;
IanBenzMaxim 27:d5aaefa252f1 288
IanBenzMaxim 32:bce180b544ed 289 return ConfigureLevel(new_level);
IanBenzMaxim 21:00c94aeb533e 290 }
IanBenzMaxim 21:00c94aeb533e 291
IanBenzMaxim 21:00c94aeb533e 292 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 293 // Set the 1-Wire Net communication speed.
IanBenzMaxim 21:00c94aeb533e 294 //
IanBenzMaxim 21:00c94aeb533e 295 // 'new_speed' - new speed defined as
IanBenzMaxim 21:00c94aeb533e 296 // MODE_STANDARD 0x00
IanBenzMaxim 21:00c94aeb533e 297 // MODE_OVERDRIVE 0x01
IanBenzMaxim 21:00c94aeb533e 298 //
IanBenzMaxim 21:00c94aeb533e 299 // Returns: current 1-Wire Net speed
IanBenzMaxim 21:00c94aeb533e 300 //
IanBenzMaxim 32:bce180b544ed 301 OneWireMaster::CmdResult DS2465::OWSetSpeed(OWSpeed new_speed)
IanBenzMaxim 21:00c94aeb533e 302 {
IanBenzMaxim 27:d5aaefa252f1 303 // Requested speed is already set
IanBenzMaxim 27:d5aaefa252f1 304 if (m_curConfig.c1WS == (new_speed == SPEED_OVERDRIVE))
IanBenzMaxim 27:d5aaefa252f1 305 return OneWireMaster::Success;
IanBenzMaxim 27:d5aaefa252f1 306
IanBenzMaxim 27:d5aaefa252f1 307 // set the speed
IanBenzMaxim 27:d5aaefa252f1 308 m_curConfig.c1WS = (new_speed == SPEED_OVERDRIVE);
IanBenzMaxim 21:00c94aeb533e 309
IanBenzMaxim 27:d5aaefa252f1 310 // write the new config
IanBenzMaxim 27:d5aaefa252f1 311 return WriteConfig(m_curConfig);
IanBenzMaxim 21:00c94aeb533e 312 }
IanBenzMaxim 21:00c94aeb533e 313
IanBenzMaxim 21:00c94aeb533e 314 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 315 // Use the DS2465 help command '1-Wire triplet' to perform one bit of a 1-Wire
IanBenzMaxim 21:00c94aeb533e 316 // search. This command does two read bits and one write bit. The write bit
IanBenzMaxim 21:00c94aeb533e 317 // is either the default direction (all device have same bit) or in case of
IanBenzMaxim 21:00c94aeb533e 318 // a discripancy, the 'search_direction' parameter is used.
IanBenzMaxim 21:00c94aeb533e 319 //
j3 22:686273e55cdc 320 // Returns � The DS2465 status byte result from the triplet command
IanBenzMaxim 21:00c94aeb533e 321 //
IanBenzMaxim 32:bce180b544ed 322 OneWireMaster::CmdResult DS2465::OWTriplet(SearchDirection & search_direction, std::uint8_t & sbr, std::uint8_t & tsb)
IanBenzMaxim 21:00c94aeb533e 323 {
IanBenzMaxim 21:00c94aeb533e 324 // 1-Wire Triplet (Case B)
IanBenzMaxim 21:00c94aeb533e 325 // S AD,0 [A] 1WT [A] SS [A] Sr AD,1 [A] [Status] A [Status] A\ P
IanBenzMaxim 21:00c94aeb533e 326 // \--------/
IanBenzMaxim 21:00c94aeb533e 327 // Repeat until 1WB bit has changed to 0
IanBenzMaxim 21:00c94aeb533e 328 // [] indicates from slave
IanBenzMaxim 21:00c94aeb533e 329 // SS indicates byte containing search direction bit value in msbit
IanBenzMaxim 24:8942d8478d68 330
IanBenzMaxim 24:8942d8478d68 331 OneWireMaster::CmdResult result;
IanBenzMaxim 27:d5aaefa252f1 332 std::uint8_t command[2] = { CMD_1WT, ((search_direction == DIRECTION_WRITE_ONE) ? 0x80 : 0x00) };
IanBenzMaxim 24:8942d8478d68 333 result = WriteMemory(ADDR_CMD_REG, command, 2);
IanBenzMaxim 24:8942d8478d68 334 if (result == OneWireMaster::Success)
IanBenzMaxim 32:bce180b544ed 335 {
IanBenzMaxim 32:bce180b544ed 336 std::uint8_t status;
IanBenzMaxim 24:8942d8478d68 337 result = PollBusy(&status);
IanBenzMaxim 32:bce180b544ed 338 if (result == OneWireMaster::Success)
IanBenzMaxim 32:bce180b544ed 339 {
IanBenzMaxim 32:bce180b544ed 340 // check bit results in status byte
IanBenzMaxim 32:bce180b544ed 341 sbr = ((status & STATUS_SBR) == STATUS_SBR);
IanBenzMaxim 32:bce180b544ed 342 tsb = ((status & STATUS_TSB) == STATUS_TSB);
IanBenzMaxim 32:bce180b544ed 343 search_direction = ((status & STATUS_DIR) == STATUS_DIR) ? DIRECTION_WRITE_ONE : DIRECTION_WRITE_ZERO;
IanBenzMaxim 32:bce180b544ed 344 }
IanBenzMaxim 32:bce180b544ed 345 }
IanBenzMaxim 24:8942d8478d68 346 return result;
IanBenzMaxim 21:00c94aeb533e 347 }
IanBenzMaxim 21:00c94aeb533e 348
IanBenzMaxim 21:00c94aeb533e 349 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 350 // The 'OWReadBlock' receives a block of data from the
IanBenzMaxim 21:00c94aeb533e 351 // 1-Wire Net. The destination is the mac buffer (rx_mac=1) or
IanBenzMaxim 21:00c94aeb533e 352 // the scratchpad (rx_mac=0). The result is buffer is returned.
IanBenzMaxim 21:00c94aeb533e 353 //
IanBenzMaxim 21:00c94aeb533e 354 // 'rx_buf' - pointer to a block to receive bytes
IanBenzMaxim 21:00c94aeb533e 355 // of length 'rx_len' from 1-Wire Net
IanBenzMaxim 21:00c94aeb533e 356 // 'rx_len' - length in bytes to read. Only valid numbers are 8,16,20,32;
IanBenzMaxim 21:00c94aeb533e 357 //
IanBenzMaxim 27:d5aaefa252f1 358 OneWireMaster::CmdResult DS2465::OWReadBlock(std::uint8_t *rx_buf, std::uint8_t rx_len)
IanBenzMaxim 21:00c94aeb533e 359 {
IanBenzMaxim 21:00c94aeb533e 360 // 1-Wire Receive Block (Case A)
IanBenzMaxim 21:00c94aeb533e 361 // S AD,0 [A] ADDR_CMD_REG [A] 1WRF [A] PR [A] P
IanBenzMaxim 21:00c94aeb533e 362 // [] indicates from slave
IanBenzMaxim 21:00c94aeb533e 363 // PR indicates byte containing parameter
IanBenzMaxim 21:00c94aeb533e 364
IanBenzMaxim 24:8942d8478d68 365 OneWireMaster::CmdResult result;
IanBenzMaxim 27:d5aaefa252f1 366 std::uint8_t command[2] = { CMD_1WRF, rx_len };
IanBenzMaxim 24:8942d8478d68 367
IanBenzMaxim 24:8942d8478d68 368 result = WriteMemory(ADDR_CMD_REG, command, 2);
IanBenzMaxim 24:8942d8478d68 369 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 370 result = PollBusy();
IanBenzMaxim 24:8942d8478d68 371 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 372 result = ReadMemory(ADDR_SPAD, rx_buf, rx_len, false);
IanBenzMaxim 21:00c94aeb533e 373
IanBenzMaxim 24:8942d8478d68 374 return result;
IanBenzMaxim 21:00c94aeb533e 375 }
IanBenzMaxim 21:00c94aeb533e 376
IanBenzMaxim 21:00c94aeb533e 377
IanBenzMaxim 21:00c94aeb533e 378
IanBenzMaxim 21:00c94aeb533e 379
IanBenzMaxim 27:d5aaefa252f1 380 OneWireMaster::CmdResult DS2465::OWWriteBlock(const std::uint8_t *tran_buf, std::uint8_t tran_len)
IanBenzMaxim 21:00c94aeb533e 381 {
IanBenzMaxim 21:00c94aeb533e 382 return OWWriteBlock(false, tran_buf, tran_len);
IanBenzMaxim 21:00c94aeb533e 383 }
IanBenzMaxim 21:00c94aeb533e 384
IanBenzMaxim 21:00c94aeb533e 385 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 386 // The 'OWWriteBlock' transfers a block of data to the
IanBenzMaxim 21:00c94aeb533e 387 // 1-Wire Net. The mac buffer can be sent (tx_mac=1) or a
IanBenzMaxim 21:00c94aeb533e 388 // portion of the scratchpad can be sent.
IanBenzMaxim 21:00c94aeb533e 389 //
IanBenzMaxim 21:00c94aeb533e 390 // 'tx_mac' - flag to indicate if the MAC buffer is to be sent (1) or
IanBenzMaxim 21:00c94aeb533e 391 // the data provided in teh tran_buf is to be sent (0)
IanBenzMaxim 21:00c94aeb533e 392 // 'tran_buf' - pointer to a block of bytes
IanBenzMaxim 21:00c94aeb533e 393 // of length 'tran_len' that will be sent
IanBenzMaxim 21:00c94aeb533e 394 // to the 1-Wire Net
IanBenzMaxim 21:00c94aeb533e 395 // 'tran_len' - length in bytes to transfer. Only valid numbers are 8,16,20,32;
IanBenzMaxim 21:00c94aeb533e 396 //
IanBenzMaxim 27:d5aaefa252f1 397 OneWireMaster::CmdResult DS2465::OWWriteBlock(bool tx_mac, const std::uint8_t *tran_buf, std::uint8_t tran_len)
IanBenzMaxim 21:00c94aeb533e 398 {
IanBenzMaxim 21:00c94aeb533e 399 OneWireMaster::CmdResult result;
IanBenzMaxim 27:d5aaefa252f1 400 std::uint8_t command[2] = { CMD_1WTB, (tx_mac ? 0xFF : tran_len) };
IanBenzMaxim 21:00c94aeb533e 401
IanBenzMaxim 24:8942d8478d68 402 if (!tx_mac)
IanBenzMaxim 21:00c94aeb533e 403 {
IanBenzMaxim 21:00c94aeb533e 404 // prefill scratchpad with required data
IanBenzMaxim 24:8942d8478d68 405 result = WriteMemory(ADDR_SPAD, tran_buf, tran_len);
IanBenzMaxim 21:00c94aeb533e 406 if (result != OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 407 return result;
IanBenzMaxim 21:00c94aeb533e 408 }
IanBenzMaxim 21:00c94aeb533e 409
IanBenzMaxim 21:00c94aeb533e 410 // 1-Wire Transmit Block (Case A)
IanBenzMaxim 21:00c94aeb533e 411 // S AD,0 [A] ADDR_CMD_REG [A] 1WTB [A] PR [A] P
IanBenzMaxim 21:00c94aeb533e 412 // [] indicates from slave
IanBenzMaxim 21:00c94aeb533e 413 // PR indicates byte containing parameter
IanBenzMaxim 24:8942d8478d68 414
IanBenzMaxim 24:8942d8478d68 415 result = WriteMemory(ADDR_CMD_REG, command, 2);
IanBenzMaxim 24:8942d8478d68 416
IanBenzMaxim 24:8942d8478d68 417 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 418 result = PollBusy();
IanBenzMaxim 21:00c94aeb533e 419
IanBenzMaxim 24:8942d8478d68 420 return result;
IanBenzMaxim 21:00c94aeb533e 421 }
IanBenzMaxim 21:00c94aeb533e 422
IanBenzMaxim 21:00c94aeb533e 423 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 424 // Send 8 bits of read communication to the 1-Wire Net and return the
IanBenzMaxim 21:00c94aeb533e 425 // result 8 bits read from the 1-Wire Net.
IanBenzMaxim 21:00c94aeb533e 426 //
IanBenzMaxim 21:00c94aeb533e 427 // Returns: 8 bits read from 1-Wire Net
IanBenzMaxim 21:00c94aeb533e 428 //
IanBenzMaxim 32:bce180b544ed 429 OneWireMaster::CmdResult DS2465::OWReadByte(std::uint8_t & recvbyte, OWLevel after_level)
IanBenzMaxim 21:00c94aeb533e 430 {
IanBenzMaxim 24:8942d8478d68 431 OneWireMaster::CmdResult result;
IanBenzMaxim 27:d5aaefa252f1 432 std::uint8_t buf;
IanBenzMaxim 21:00c94aeb533e 433
IanBenzMaxim 24:8942d8478d68 434 // 1-Wire Read Bytes (Case C)
IanBenzMaxim 24:8942d8478d68 435 // S AD,0 [A] ADDR_CMD_REG [A] 1WRB [A] Sr AD,1 [A] [Status] A [Status] A
IanBenzMaxim 24:8942d8478d68 436 // \--------/
IanBenzMaxim 24:8942d8478d68 437 // Repeat until 1WB bit has changed to 0
IanBenzMaxim 24:8942d8478d68 438 // Sr AD,0 [A] SRP [A] E1 [A] Sr AD,1 [A] DD A\ P
IanBenzMaxim 24:8942d8478d68 439 //
IanBenzMaxim 24:8942d8478d68 440 // [] indicates from slave
IanBenzMaxim 24:8942d8478d68 441 // DD data read
IanBenzMaxim 26:a361e3f42ba5 442
IanBenzMaxim 32:bce180b544ed 443 result = ConfigureLevel(after_level);
IanBenzMaxim 26:a361e3f42ba5 444 if (result != OneWireMaster::Success)
IanBenzMaxim 26:a361e3f42ba5 445 return result;
IanBenzMaxim 24:8942d8478d68 446
IanBenzMaxim 24:8942d8478d68 447 buf = CMD_1WRB;
IanBenzMaxim 24:8942d8478d68 448 result = WriteMemory(ADDR_CMD_REG, &buf, 1);
IanBenzMaxim 21:00c94aeb533e 449
IanBenzMaxim 24:8942d8478d68 450 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 451 result = PollBusy();
IanBenzMaxim 24:8942d8478d68 452
IanBenzMaxim 24:8942d8478d68 453 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 454 result = ReadMemory(ADDR_DATA_REG, &buf, 1);
IanBenzMaxim 21:00c94aeb533e 455
IanBenzMaxim 24:8942d8478d68 456 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 457 recvbyte = buf;
IanBenzMaxim 21:00c94aeb533e 458
IanBenzMaxim 24:8942d8478d68 459 return result;
IanBenzMaxim 21:00c94aeb533e 460 }
IanBenzMaxim 21:00c94aeb533e 461
IanBenzMaxim 21:00c94aeb533e 462 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 463 // Send 8 bits of communication to the 1-Wire Net and verify that the
IanBenzMaxim 21:00c94aeb533e 464 // 8 bits read from the 1-Wire Net is the same (write operation).
IanBenzMaxim 21:00c94aeb533e 465 // The parameter 'sendbyte' least significant 8 bits are used.
IanBenzMaxim 21:00c94aeb533e 466 //
IanBenzMaxim 21:00c94aeb533e 467 // 'sendbyte' - 8 bits to send (least significant byte)
IanBenzMaxim 21:00c94aeb533e 468 //
IanBenzMaxim 21:00c94aeb533e 469 // Returns: true: bytes written and echo was the same
IanBenzMaxim 21:00c94aeb533e 470 // false: echo was not the same
IanBenzMaxim 21:00c94aeb533e 471 //
IanBenzMaxim 32:bce180b544ed 472 OneWireMaster::CmdResult DS2465::OWWriteByte(std::uint8_t sendbyte, OWLevel after_level)
IanBenzMaxim 24:8942d8478d68 473 {
IanBenzMaxim 21:00c94aeb533e 474 // 1-Wire Write Byte (Case B)
IanBenzMaxim 21:00c94aeb533e 475 // S AD,0 [A] ADDR_CMD_REG [A] 1WWB [A] DD [A] Sr AD,1 [A] [Status] A [Status] A\ P
IanBenzMaxim 21:00c94aeb533e 476 // \--------/
IanBenzMaxim 21:00c94aeb533e 477 // Repeat until 1WB bit has changed to 0
IanBenzMaxim 21:00c94aeb533e 478 // [] indicates from slave
IanBenzMaxim 21:00c94aeb533e 479 // DD data to write
IanBenzMaxim 24:8942d8478d68 480
IanBenzMaxim 24:8942d8478d68 481 OneWireMaster::CmdResult result;
IanBenzMaxim 26:a361e3f42ba5 482
IanBenzMaxim 32:bce180b544ed 483 result = ConfigureLevel(after_level);
IanBenzMaxim 26:a361e3f42ba5 484 if (result != OneWireMaster::Success)
IanBenzMaxim 26:a361e3f42ba5 485 return result;
IanBenzMaxim 26:a361e3f42ba5 486
IanBenzMaxim 27:d5aaefa252f1 487 std::uint8_t command[2] = { CMD_1WWB, sendbyte };
IanBenzMaxim 24:8942d8478d68 488
IanBenzMaxim 24:8942d8478d68 489 result = WriteMemory(ADDR_CMD_REG, command, 2);
IanBenzMaxim 24:8942d8478d68 490 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 491 result = PollBusy();
IanBenzMaxim 21:00c94aeb533e 492
IanBenzMaxim 24:8942d8478d68 493 return result;
IanBenzMaxim 21:00c94aeb533e 494 }
IanBenzMaxim 21:00c94aeb533e 495
IanBenzMaxim 21:00c94aeb533e 496 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 497 // Send 1 bit of communication to the 1-Wire Net and return the
IanBenzMaxim 21:00c94aeb533e 498 // result 1 bit read from the 1-Wire Net. The parameter 'sendbit'
IanBenzMaxim 21:00c94aeb533e 499 // least significant bit is used and the least significant bit
IanBenzMaxim 21:00c94aeb533e 500 // of the result is the return bit.
IanBenzMaxim 21:00c94aeb533e 501 //
IanBenzMaxim 21:00c94aeb533e 502 // 'sendbit' - the least significant bit is the bit to send
IanBenzMaxim 21:00c94aeb533e 503 //
IanBenzMaxim 21:00c94aeb533e 504 // Returns: 0: 0 bit read from sendbit
IanBenzMaxim 21:00c94aeb533e 505 // 1: 1 bit read from sendbit
IanBenzMaxim 21:00c94aeb533e 506 //
IanBenzMaxim 32:bce180b544ed 507 OneWireMaster::CmdResult DS2465::OWTouchBit(std::uint8_t & sendrecvbit, OWLevel after_level)
IanBenzMaxim 21:00c94aeb533e 508 {
IanBenzMaxim 21:00c94aeb533e 509 // 1-Wire bit (Case B)
IanBenzMaxim 21:00c94aeb533e 510 // S AD,0 [A] ADDR_CMD_REG [A] 1WSB [A] BB [A] Sr AD,1 [A] [Status] A [Status] A\ P
IanBenzMaxim 21:00c94aeb533e 511 // \--------/
IanBenzMaxim 21:00c94aeb533e 512 // Repeat until 1WB bit has changed to 0
IanBenzMaxim 21:00c94aeb533e 513 // [] indicates from slave
IanBenzMaxim 21:00c94aeb533e 514 // BB indicates byte containing bit value in msbit
IanBenzMaxim 21:00c94aeb533e 515
IanBenzMaxim 24:8942d8478d68 516 OneWireMaster::CmdResult result;
IanBenzMaxim 26:a361e3f42ba5 517
IanBenzMaxim 32:bce180b544ed 518 result = ConfigureLevel(after_level);
IanBenzMaxim 26:a361e3f42ba5 519 if (result != OneWireMaster::Success)
IanBenzMaxim 26:a361e3f42ba5 520 return result;
IanBenzMaxim 26:a361e3f42ba5 521
IanBenzMaxim 27:d5aaefa252f1 522 std::uint8_t command[2] = { CMD_1WSB, (sendrecvbit ? 0x80 : 0x00) };
IanBenzMaxim 27:d5aaefa252f1 523 std::uint8_t status;
IanBenzMaxim 24:8942d8478d68 524
IanBenzMaxim 24:8942d8478d68 525 result = WriteMemory(ADDR_CMD_REG, command, 2);
IanBenzMaxim 21:00c94aeb533e 526
IanBenzMaxim 24:8942d8478d68 527 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 528 result = PollBusy(&status);
IanBenzMaxim 21:00c94aeb533e 529
IanBenzMaxim 24:8942d8478d68 530 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 531 sendrecvbit = (status & STATUS_SBR);
IanBenzMaxim 24:8942d8478d68 532
IanBenzMaxim 24:8942d8478d68 533 return result;
IanBenzMaxim 21:00c94aeb533e 534 }
IanBenzMaxim 21:00c94aeb533e 535
IanBenzMaxim 21:00c94aeb533e 536 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 537 // Write to Scratchpad (SRAM) memory on the DS2465
IanBenzMaxim 21:00c94aeb533e 538 //
IanBenzMaxim 21:00c94aeb533e 539 // 'addr' - address to start writing (must be in SRAM)
IanBenzMaxim 21:00c94aeb533e 540 // 'buf' - buffer of data to write
IanBenzMaxim 21:00c94aeb533e 541 // 'len' - length to write
IanBenzMaxim 21:00c94aeb533e 542 //
IanBenzMaxim 21:00c94aeb533e 543 // Returns: true write successful
IanBenzMaxim 21:00c94aeb533e 544 // false failure to complete write
IanBenzMaxim 21:00c94aeb533e 545 //
IanBenzMaxim 27:d5aaefa252f1 546 OneWireMaster::CmdResult DS2465::CWriteMemory(std::uint8_t addr, const std::uint8_t * buf, std::size_t bufLen) const
IanBenzMaxim 21:00c94aeb533e 547 {
IanBenzMaxim 21:00c94aeb533e 548 int i;
IanBenzMaxim 21:00c94aeb533e 549
IanBenzMaxim 21:00c94aeb533e 550 // Write SRAM (Case A)
IanBenzMaxim 21:00c94aeb533e 551 // S AD,0 [A] VSA [A] DD [A] P
IanBenzMaxim 21:00c94aeb533e 552 // \-----/
IanBenzMaxim 21:00c94aeb533e 553 // Repeat for each data byte
IanBenzMaxim 21:00c94aeb533e 554 // [] indicates from slave
IanBenzMaxim 21:00c94aeb533e 555 // VSA valid SRAM memory address
IanBenzMaxim 21:00c94aeb533e 556 // DD memory data to write
IanBenzMaxim 21:00c94aeb533e 557
IanBenzMaxim 21:00c94aeb533e 558 m_I2C_interface.start();
IanBenzMaxim 32:bce180b544ed 559 if (m_I2C_interface.write((m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK)
IanBenzMaxim 21:00c94aeb533e 560 {
IanBenzMaxim 21:00c94aeb533e 561 m_I2C_interface.stop();
IanBenzMaxim 21:00c94aeb533e 562 return OneWireMaster::CommunicationWriteError;
IanBenzMaxim 21:00c94aeb533e 563 }
IanBenzMaxim 32:bce180b544ed 564 if (m_I2C_interface.write(addr) != I2C_WRITE_OK)
IanBenzMaxim 21:00c94aeb533e 565 {
IanBenzMaxim 21:00c94aeb533e 566 m_I2C_interface.stop();
IanBenzMaxim 21:00c94aeb533e 567 return OneWireMaster::CommunicationWriteError;
IanBenzMaxim 21:00c94aeb533e 568 }
IanBenzMaxim 21:00c94aeb533e 569 // loop to write each byte
IanBenzMaxim 21:00c94aeb533e 570 for (i = 0; i < bufLen; i++)
IanBenzMaxim 21:00c94aeb533e 571 {
IanBenzMaxim 21:00c94aeb533e 572 if (m_I2C_interface.write(buf[i]) != I2C_WRITE_OK)
IanBenzMaxim 21:00c94aeb533e 573 {
IanBenzMaxim 21:00c94aeb533e 574 m_I2C_interface.stop();
IanBenzMaxim 21:00c94aeb533e 575 return OneWireMaster::CommunicationWriteError;
IanBenzMaxim 21:00c94aeb533e 576 }
IanBenzMaxim 21:00c94aeb533e 577 }
IanBenzMaxim 21:00c94aeb533e 578 m_I2C_interface.stop();
IanBenzMaxim 21:00c94aeb533e 579
IanBenzMaxim 21:00c94aeb533e 580 return OneWireMaster::Success;
IanBenzMaxim 21:00c94aeb533e 581 }
IanBenzMaxim 21:00c94aeb533e 582
IanBenzMaxim 21:00c94aeb533e 583 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 584 // Read memory from the DS2465
IanBenzMaxim 21:00c94aeb533e 585 //
IanBenzMaxim 21:00c94aeb533e 586 // 'addr' - address to start reading
IanBenzMaxim 21:00c94aeb533e 587 // 'buf' - buffer to hold memory read
IanBenzMaxim 21:00c94aeb533e 588 // 'len' - length to read
IanBenzMaxim 21:00c94aeb533e 589 // 'skip_set_pointer' - flag to indicate to skip setting address pointer
IanBenzMaxim 21:00c94aeb533e 590 //
IanBenzMaxim 21:00c94aeb533e 591 // Returns: true read successful
IanBenzMaxim 21:00c94aeb533e 592 // false failure to complete read
IanBenzMaxim 21:00c94aeb533e 593 //
IanBenzMaxim 27:d5aaefa252f1 594 OneWireMaster::CmdResult DS2465::ReadMemory(std::uint8_t addr, std::uint8_t * buf, std::size_t bufLen, bool skip_set_pointer) const
IanBenzMaxim 21:00c94aeb533e 595 {
IanBenzMaxim 21:00c94aeb533e 596 int i;
IanBenzMaxim 21:00c94aeb533e 597
IanBenzMaxim 21:00c94aeb533e 598 // Read (Case A)
IanBenzMaxim 21:00c94aeb533e 599 // S AD,0 [A] MA [A] Sr AD,1 [A] [DD] A [DD] A\ P
IanBenzMaxim 21:00c94aeb533e 600 // \-----/
IanBenzMaxim 21:00c94aeb533e 601 // Repeat for each data byte, NAK last byte
IanBenzMaxim 21:00c94aeb533e 602 // [] indicates from slave
IanBenzMaxim 21:00c94aeb533e 603 // MA memory address
IanBenzMaxim 21:00c94aeb533e 604 // DD memory data read
IanBenzMaxim 21:00c94aeb533e 605
IanBenzMaxim 21:00c94aeb533e 606 m_I2C_interface.start();
IanBenzMaxim 21:00c94aeb533e 607 if (!skip_set_pointer)
IanBenzMaxim 21:00c94aeb533e 608 {
IanBenzMaxim 32:bce180b544ed 609 if (m_I2C_interface.write((m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK)
IanBenzMaxim 21:00c94aeb533e 610 {
IanBenzMaxim 21:00c94aeb533e 611 m_I2C_interface.stop();
IanBenzMaxim 21:00c94aeb533e 612 return OneWireMaster::CommunicationWriteError;
IanBenzMaxim 21:00c94aeb533e 613 }
IanBenzMaxim 32:bce180b544ed 614 if (m_I2C_interface.write(addr) != I2C_WRITE_OK)
IanBenzMaxim 21:00c94aeb533e 615 {
IanBenzMaxim 21:00c94aeb533e 616 m_I2C_interface.stop();
IanBenzMaxim 21:00c94aeb533e 617 return OneWireMaster::CommunicationWriteError;
IanBenzMaxim 21:00c94aeb533e 618 }
IanBenzMaxim 21:00c94aeb533e 619 m_I2C_interface.start();
IanBenzMaxim 21:00c94aeb533e 620 }
IanBenzMaxim 21:00c94aeb533e 621
IanBenzMaxim 32:bce180b544ed 622 if (m_I2C_interface.write((m_I2C_address | I2C_READ)) != I2C_WRITE_OK)
IanBenzMaxim 21:00c94aeb533e 623 {
IanBenzMaxim 21:00c94aeb533e 624 m_I2C_interface.stop();
IanBenzMaxim 21:00c94aeb533e 625 return OneWireMaster::CommunicationWriteError;
IanBenzMaxim 21:00c94aeb533e 626 }
IanBenzMaxim 21:00c94aeb533e 627 // loop to read each byte, NAK last byte
IanBenzMaxim 21:00c94aeb533e 628 for (i = 0; i < bufLen; i++)
IanBenzMaxim 21:00c94aeb533e 629 {
IanBenzMaxim 21:00c94aeb533e 630 buf[i] = m_I2C_interface.read((i == (bufLen - 1)) ? m_I2C_interface.NoACK : m_I2C_interface.ACK);
IanBenzMaxim 21:00c94aeb533e 631 }
IanBenzMaxim 21:00c94aeb533e 632 m_I2C_interface.stop();
IanBenzMaxim 21:00c94aeb533e 633
IanBenzMaxim 21:00c94aeb533e 634 return OneWireMaster::Success;
IanBenzMaxim 21:00c94aeb533e 635 }
IanBenzMaxim 21:00c94aeb533e 636
IanBenzMaxim 21:00c94aeb533e 637 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 638 // Write the configuration register in the DS2465. The configuration
IanBenzMaxim 21:00c94aeb533e 639 // options are provided in the lower nibble of the provided config byte.
IanBenzMaxim 21:00c94aeb533e 640 // The uppper nibble in bitwise inverted when written to the DS2465.
IanBenzMaxim 21:00c94aeb533e 641 //
IanBenzMaxim 21:00c94aeb533e 642 // Returns: true: config written and response correct
IanBenzMaxim 21:00c94aeb533e 643 // false: response incorrect
IanBenzMaxim 21:00c94aeb533e 644 //
IanBenzMaxim 24:8942d8478d68 645 OneWireMaster::CmdResult DS2465::WriteConfig(const Config & config)
IanBenzMaxim 21:00c94aeb533e 646 {
IanBenzMaxim 24:8942d8478d68 647 std::uint8_t configBuf;
IanBenzMaxim 24:8942d8478d68 648 OneWireMaster::CmdResult result;
IanBenzMaxim 21:00c94aeb533e 649
IanBenzMaxim 24:8942d8478d68 650 configBuf = config.writeByte();
IanBenzMaxim 24:8942d8478d68 651 result = WriteMemory(ADDR_WCFG_REG, &configBuf, 1);
IanBenzMaxim 24:8942d8478d68 652 if (result == OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 653 {
IanBenzMaxim 24:8942d8478d68 654 result = ReadMemory(ADDR_WCFG_REG, &configBuf, 1);
IanBenzMaxim 24:8942d8478d68 655 }
IanBenzMaxim 24:8942d8478d68 656 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 657 {
IanBenzMaxim 24:8942d8478d68 658 if (configBuf != config.readByte())
IanBenzMaxim 24:8942d8478d68 659 result = OneWireMaster::OperationFailure;
IanBenzMaxim 21:00c94aeb533e 660 }
IanBenzMaxim 21:00c94aeb533e 661
IanBenzMaxim 24:8942d8478d68 662 return result;
IanBenzMaxim 24:8942d8478d68 663 }
IanBenzMaxim 24:8942d8478d68 664
IanBenzMaxim 24:8942d8478d68 665
IanBenzMaxim 24:8942d8478d68 666
IanBenzMaxim 32:bce180b544ed 667 DS2465::Config DS2465::CurrentConfig() const
IanBenzMaxim 32:bce180b544ed 668 {
IanBenzMaxim 32:bce180b544ed 669 return m_curConfig;
IanBenzMaxim 32:bce180b544ed 670 }
IanBenzMaxim 32:bce180b544ed 671
IanBenzMaxim 32:bce180b544ed 672
IanBenzMaxim 32:bce180b544ed 673
IanBenzMaxim 24:8942d8478d68 674
IanBenzMaxim 27:d5aaefa252f1 675 OneWireMaster::CmdResult DS2465::PollBusy(std::uint8_t * pStatus)
IanBenzMaxim 24:8942d8478d68 676 {
IanBenzMaxim 24:8942d8478d68 677 const unsigned int pollLimit = 200;
IanBenzMaxim 24:8942d8478d68 678
IanBenzMaxim 24:8942d8478d68 679 OneWireMaster::CmdResult result;
IanBenzMaxim 27:d5aaefa252f1 680 std::uint8_t status;
IanBenzMaxim 24:8942d8478d68 681 unsigned int pollCount = 0;
IanBenzMaxim 24:8942d8478d68 682
IanBenzMaxim 24:8942d8478d68 683 // loop checking 1WB bit for completion of 1-Wire operation
IanBenzMaxim 24:8942d8478d68 684 // abort if poll limit reached
IanBenzMaxim 24:8942d8478d68 685
IanBenzMaxim 24:8942d8478d68 686 do
IanBenzMaxim 24:8942d8478d68 687 {
IanBenzMaxim 24:8942d8478d68 688 result = ReadMemory(ADDR_STATUS_REG, &status, 1, true);
IanBenzMaxim 24:8942d8478d68 689 if (result != OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 690 return result;
IanBenzMaxim 24:8942d8478d68 691 if (pStatus != NULL)
IanBenzMaxim 24:8942d8478d68 692 *pStatus = status;
IanBenzMaxim 24:8942d8478d68 693 if (pollCount++ >= pollLimit)
IanBenzMaxim 24:8942d8478d68 694 return OneWireMaster::TimeoutError;
IanBenzMaxim 24:8942d8478d68 695 } while (status & STATUS_1WB);
IanBenzMaxim 24:8942d8478d68 696
IanBenzMaxim 21:00c94aeb533e 697 return OneWireMaster::Success;
IanBenzMaxim 21:00c94aeb533e 698 }
IanBenzMaxim 21:00c94aeb533e 699
IanBenzMaxim 21:00c94aeb533e 700 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 701 // Reset all of the devices on the 1-Wire Net and return the result.
IanBenzMaxim 21:00c94aeb533e 702 //
IanBenzMaxim 21:00c94aeb533e 703 // Returns: true(1): presense pulse(s) detected, device(s) reset
IanBenzMaxim 21:00c94aeb533e 704 // false(0): no presense pulses detected
IanBenzMaxim 21:00c94aeb533e 705 //
IanBenzMaxim 21:00c94aeb533e 706 OneWireMaster::CmdResult DS2465::OWReset(void)
IanBenzMaxim 24:8942d8478d68 707 {
IanBenzMaxim 24:8942d8478d68 708 // 1-Wire reset (Case B)
IanBenzMaxim 24:8942d8478d68 709 // S AD,0 [A] ADDR_CMD_REG [A] 1WRS [A] Sr AD,1 [A] [Status] A [Status] A\ P
IanBenzMaxim 24:8942d8478d68 710 // \--------/
IanBenzMaxim 24:8942d8478d68 711 // Repeat until 1WB bit has changed to 0
IanBenzMaxim 24:8942d8478d68 712 // [] indicates from slave
IanBenzMaxim 21:00c94aeb533e 713
IanBenzMaxim 24:8942d8478d68 714 OneWireMaster::CmdResult result;
IanBenzMaxim 27:d5aaefa252f1 715 std::uint8_t buf;
IanBenzMaxim 21:00c94aeb533e 716
IanBenzMaxim 24:8942d8478d68 717 buf = CMD_1WRS;
IanBenzMaxim 24:8942d8478d68 718 result = WriteMemory(ADDR_CMD_REG, &buf, 1);
IanBenzMaxim 21:00c94aeb533e 719
IanBenzMaxim 24:8942d8478d68 720 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 721 result = PollBusy(&buf);
IanBenzMaxim 24:8942d8478d68 722
IanBenzMaxim 24:8942d8478d68 723 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 724 {
IanBenzMaxim 24:8942d8478d68 725 // check for presence detect
IanBenzMaxim 24:8942d8478d68 726 if ((buf & STATUS_PPD) != STATUS_PPD)
IanBenzMaxim 24:8942d8478d68 727 result = OneWireMaster::OperationFailure;
IanBenzMaxim 24:8942d8478d68 728 }
IanBenzMaxim 21:00c94aeb533e 729
IanBenzMaxim 24:8942d8478d68 730 return result;
IanBenzMaxim 21:00c94aeb533e 731 }
IanBenzMaxim 21:00c94aeb533e 732
IanBenzMaxim 21:00c94aeb533e 733 OneWireMaster::CmdResult DS2465::Reset(void)
IanBenzMaxim 24:8942d8478d68 734 {
IanBenzMaxim 21:00c94aeb533e 735 // Device Reset
IanBenzMaxim 21:00c94aeb533e 736 // S AD,0 [A] ADDR_CMD_REG [A] 1WMR [A] Sr AD,1 [A] [SS] A\ P
IanBenzMaxim 21:00c94aeb533e 737 // [] indicates from slave
IanBenzMaxim 21:00c94aeb533e 738 // SS status byte to read to verify state
IanBenzMaxim 21:00c94aeb533e 739
IanBenzMaxim 24:8942d8478d68 740 OneWireMaster::CmdResult result;
IanBenzMaxim 27:d5aaefa252f1 741 std::uint8_t buf;
IanBenzMaxim 21:00c94aeb533e 742
IanBenzMaxim 24:8942d8478d68 743 buf = CMD_1WMR;
IanBenzMaxim 24:8942d8478d68 744 result = WriteMemory(ADDR_CMD_REG, &buf, 1);
IanBenzMaxim 21:00c94aeb533e 745
IanBenzMaxim 24:8942d8478d68 746 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 747 result = ReadMemory(ADDR_STATUS_REG, &buf, 1, true);
IanBenzMaxim 24:8942d8478d68 748
IanBenzMaxim 24:8942d8478d68 749 if (result == OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 750 {
IanBenzMaxim 24:8942d8478d68 751 if ((buf & 0xF7) != 0x10)
IanBenzMaxim 24:8942d8478d68 752 result = OneWireMaster::OperationFailure;
IanBenzMaxim 21:00c94aeb533e 753 }
IanBenzMaxim 24:8942d8478d68 754
IanBenzMaxim 24:8942d8478d68 755 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 756 OWReset(); // do a command to get 1-Wire master reset out of holding state
IanBenzMaxim 21:00c94aeb533e 757
IanBenzMaxim 24:8942d8478d68 758 return result;
IanBenzMaxim 21:00c94aeb533e 759 }
IanBenzMaxim 21:00c94aeb533e 760
IanBenzMaxim 21:00c94aeb533e 761 OneWireMaster::CmdResult DS2465::Detect(void)
IanBenzMaxim 21:00c94aeb533e 762 {
IanBenzMaxim 21:00c94aeb533e 763 OneWireMaster::CmdResult result;
IanBenzMaxim 21:00c94aeb533e 764
IanBenzMaxim 21:00c94aeb533e 765 // reset DS2465
IanBenzMaxim 21:00c94aeb533e 766 result = Reset();
IanBenzMaxim 21:00c94aeb533e 767 if (result != OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 768 return result;
IanBenzMaxim 21:00c94aeb533e 769
IanBenzMaxim 21:00c94aeb533e 770 // default configuration
IanBenzMaxim 24:8942d8478d68 771 m_curConfig.reset();
IanBenzMaxim 21:00c94aeb533e 772
IanBenzMaxim 21:00c94aeb533e 773 // write the default configuration setup
IanBenzMaxim 24:8942d8478d68 774 result = WriteConfig(m_curConfig);
IanBenzMaxim 21:00c94aeb533e 775 return result;
IanBenzMaxim 21:00c94aeb533e 776 }