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:
Wed Mar 30 16:50:29 2016 -0500
Revision:
32:bce180b544ed
Parent:
27:d5aaefa252f1
Child:
33:a4c015046956
1. Move the implementation of OWSearch() into OneWireMaster since it is a fairly complex algorithm that shouldn?t be implemented over and over. It will also match all other ROM function that are implemented there.
2. Create a new member function, OWTriplet(), in OneWireMaster to handle the virtual section of OWSearch(). Create a default implementation of OWTriplet() that uses OWReadByte() and OWWriteByte(). Masters only need to implement this function if they have a search accelerator of some sort.
3. Create type SearchState that will encapsulate all persistent data used by the search ROM functions. This will also make it easy to not have the search state part of the permanent OneWireMaster class data.
4. Rename OWSpeed() to OWSetSpeed() and OWLevel() to OWSetLevel() for naming consistency.

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 21:00c94aeb533e 100 OneWireMaster::CmdResult DS2465::Compute_NextMasterSecret(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 21:00c94aeb533e 117 OneWireMaster::CmdResult DS2465::Compute_WriteMAC(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 21:00c94aeb533e 133 OneWireMaster::CmdResult DS2465::Compute_AuthMAC(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 21:00c94aeb533e 149 OneWireMaster::CmdResult DS2465::Compute_SSecret(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 21:00c94aeb533e 158 ISha256MacCoprocessor::CmdResult DS2465::setMasterSecret(const std::uint8_t (&secret)[secret_len])
IanBenzMaxim 21:00c94aeb533e 159 {
IanBenzMaxim 21:00c94aeb533e 160 OneWireMaster::CmdResult result;
IanBenzMaxim 24:8942d8478d68 161 result = WriteMemory(ADDR_SPAD, secret, secret_len);
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 21:00c94aeb533e 169 ISha256MacCoprocessor::CmdResult DS2465::ComputeAndRead_WriteMAC(const std::uint8_t (&WriteMAC_data)[WriteMAC_data_len], std::uint8_t (&mac)[mac_len]) const
IanBenzMaxim 21:00c94aeb533e 170 {
IanBenzMaxim 21:00c94aeb533e 171 OneWireMaster::CmdResult result;
IanBenzMaxim 21:00c94aeb533e 172 // Write input data to scratchpad
IanBenzMaxim 24:8942d8478d68 173 result = WriteScratchpad(WriteMAC_data, WriteMAC_data_len);
IanBenzMaxim 21:00c94aeb533e 174 // Compute MAC
IanBenzMaxim 21:00c94aeb533e 175 if (result == OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 176 result = Compute_WriteMAC(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 21:00c94aeb533e 181 result = ReadMemory(ADDR_MAC_READ, mac, mac_len, 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 21:00c94aeb533e 186 ISha256MacCoprocessor::CmdResult DS2465::ComputeAndRead_AuthMAC(const std::uint8_t (&devicePage)[devicePage_len], const std::uint8_t (&challenge)[deviceScratchpad_len],
IanBenzMaxim 21:00c94aeb533e 187 const std::uint8_t (&AuthMAC_data)[AuthMAC_data_len], std::uint8_t (&mac)[mac_len]) const
IanBenzMaxim 21:00c94aeb533e 188 {
IanBenzMaxim 21:00c94aeb533e 189 OneWireMaster::CmdResult result;
IanBenzMaxim 21:00c94aeb533e 190 int addr = ADDR_SPAD;
IanBenzMaxim 21:00c94aeb533e 191 // Write input data to scratchpad
IanBenzMaxim 24:8942d8478d68 192 result = CWriteMemory(addr, devicePage, devicePage_len);
IanBenzMaxim 21:00c94aeb533e 193 if (result == OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 194 {
IanBenzMaxim 21:00c94aeb533e 195 addr += devicePage_len;
IanBenzMaxim 24:8942d8478d68 196 result = CWriteMemory(addr, challenge, deviceScratchpad_len);
IanBenzMaxim 21:00c94aeb533e 197 }
IanBenzMaxim 21:00c94aeb533e 198 if (result == OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 199 {
IanBenzMaxim 21:00c94aeb533e 200 addr += deviceScratchpad_len;
IanBenzMaxim 24:8942d8478d68 201 result = CWriteMemory(addr, AuthMAC_data, AuthMAC_data_len);
IanBenzMaxim 21:00c94aeb533e 202 }
IanBenzMaxim 21:00c94aeb533e 203 // Compute MAC
IanBenzMaxim 21:00c94aeb533e 204 if (result == OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 205 result = Compute_AuthMAC(false, 0, REGION_FULL_PAGE);
IanBenzMaxim 21:00c94aeb533e 206 if (result == OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 207 {
IanBenzMaxim 21:00c94aeb533e 208 wait_ms(SHA_COMPUTATION_DELAY * 2);
IanBenzMaxim 21:00c94aeb533e 209 // Read MAC from register
IanBenzMaxim 21:00c94aeb533e 210 result = ReadMemory(ADDR_MAC_READ, mac, mac_len, true);
IanBenzMaxim 21:00c94aeb533e 211 }
IanBenzMaxim 21:00c94aeb533e 212 return (result == OneWireMaster::Success ? ISha256MacCoprocessor::Success : ISha256MacCoprocessor::OperationFailure);
IanBenzMaxim 21:00c94aeb533e 213 }
IanBenzMaxim 21:00c94aeb533e 214
IanBenzMaxim 32:bce180b544ed 215 ISha256MacCoprocessor::CmdResult DS2465::Compute_SSecret(const std::uint8_t (&devicePage)[devicePage_len], const std::uint8_t (&deviceScratchpad)[deviceScratchpad_len],
IanBenzMaxim 32:bce180b544ed 216 const std::uint8_t (&SSecret_data)[SSecret_data_len])
IanBenzMaxim 21:00c94aeb533e 217 {
IanBenzMaxim 21:00c94aeb533e 218 OneWireMaster::CmdResult result;
IanBenzMaxim 21:00c94aeb533e 219 int addr = ADDR_SPAD;
IanBenzMaxim 21:00c94aeb533e 220 // Write input data to scratchpad
IanBenzMaxim 24:8942d8478d68 221 result = WriteMemory(addr, devicePage, devicePage_len);
IanBenzMaxim 21:00c94aeb533e 222 if (result == OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 223 {
IanBenzMaxim 21:00c94aeb533e 224 addr += devicePage_len;
IanBenzMaxim 24:8942d8478d68 225 result = WriteMemory(addr, deviceScratchpad, deviceScratchpad_len);
IanBenzMaxim 21:00c94aeb533e 226 }
IanBenzMaxim 21:00c94aeb533e 227 if (result == OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 228 {
IanBenzMaxim 21:00c94aeb533e 229 addr += deviceScratchpad_len;
IanBenzMaxim 24:8942d8478d68 230 result = WriteMemory(addr, SSecret_data, SSecret_data_len);
IanBenzMaxim 21:00c94aeb533e 231 }
IanBenzMaxim 21:00c94aeb533e 232 // Compute secret
IanBenzMaxim 21:00c94aeb533e 233 if (result == OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 234 result = Compute_SSecret(false, 0, REGION_FULL_PAGE);
IanBenzMaxim 21:00c94aeb533e 235 if (result == OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 236 wait_ms(SHA_COMPUTATION_DELAY * 2);
IanBenzMaxim 21:00c94aeb533e 237 return (result == OneWireMaster::Success ? ISha256MacCoprocessor::Success : ISha256MacCoprocessor::OperationFailure);
IanBenzMaxim 21:00c94aeb533e 238 }
IanBenzMaxim 21:00c94aeb533e 239
IanBenzMaxim 21:00c94aeb533e 240 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 241 // Copy Scratchpad on DS2465 to either secret or memory page
IanBenzMaxim 21:00c94aeb533e 242 //
IanBenzMaxim 21:00c94aeb533e 243 // 'dest_secret' - 1 if destination is secret, 0 if memory page
IanBenzMaxim 21:00c94aeb533e 244 // 'page' - page number if dest_secret=0
IanBenzMaxim 21:00c94aeb533e 245 // 'notfull' - 0 if only 4 byte segment, 1 if writing to full page,
IanBenzMaxim 21:00c94aeb533e 246 // 'seg' - Segment number if full=0.
IanBenzMaxim 21:00c94aeb533e 247 //
IanBenzMaxim 21:00c94aeb533e 248 // Returns: true write successful
IanBenzMaxim 21:00c94aeb533e 249 // false failure to complete read
IanBenzMaxim 21:00c94aeb533e 250 //
IanBenzMaxim 21:00c94aeb533e 251 OneWireMaster::CmdResult DS2465::CopyScratchpad(bool dest_secret, unsigned int pageNum, bool notFull, unsigned int segmentNum)
IanBenzMaxim 21:00c94aeb533e 252 {
IanBenzMaxim 27:d5aaefa252f1 253 std::uint8_t command[2] = { CMD_CPS, (dest_secret ? 0 : (0x80 | (pageNum << 4) | (notFull << 3) | segmentNum)) };
IanBenzMaxim 24:8942d8478d68 254 return WriteMemory(ADDR_CMD_REG, command, 2);
IanBenzMaxim 21:00c94aeb533e 255 }
IanBenzMaxim 21:00c94aeb533e 256
IanBenzMaxim 26:a361e3f42ba5 257
IanBenzMaxim 21:00c94aeb533e 258
IanBenzMaxim 26:a361e3f42ba5 259
IanBenzMaxim 32:bce180b544ed 260 OneWireMaster::CmdResult DS2465::ConfigureLevel(OWLevel level)
IanBenzMaxim 26:a361e3f42ba5 261 {
IanBenzMaxim 26:a361e3f42ba5 262 OneWireMaster::CmdResult result;
IanBenzMaxim 32:bce180b544ed 263 if (m_curConfig.cSPU != (level == LEVEL_STRONG))
IanBenzMaxim 26:a361e3f42ba5 264 {
IanBenzMaxim 32:bce180b544ed 265 m_curConfig.cSPU = (level == LEVEL_STRONG);
IanBenzMaxim 32:bce180b544ed 266 result = WriteConfig(m_curConfig);
IanBenzMaxim 21:00c94aeb533e 267 }
IanBenzMaxim 26:a361e3f42ba5 268 else
IanBenzMaxim 26:a361e3f42ba5 269 {
IanBenzMaxim 26:a361e3f42ba5 270 result = OneWireMaster::Success;
IanBenzMaxim 26:a361e3f42ba5 271 }
IanBenzMaxim 21:00c94aeb533e 272 return result;
IanBenzMaxim 21:00c94aeb533e 273 }
IanBenzMaxim 21:00c94aeb533e 274
IanBenzMaxim 21:00c94aeb533e 275 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 276 // Set the 1-Wire Net line level pull-up to normal. The DS2465 does only
IanBenzMaxim 21:00c94aeb533e 277 // allows enabling strong pull-up on a bit or byte event. Consequently this
IanBenzMaxim 21:00c94aeb533e 278 // function only allows the MODE_STANDARD argument. To enable strong pull-up
IanBenzMaxim 21:00c94aeb533e 279 // use OWWriteBytePower or OWReadBitPower.
IanBenzMaxim 21:00c94aeb533e 280 //
IanBenzMaxim 21:00c94aeb533e 281 // 'new_level' - new level defined as
IanBenzMaxim 21:00c94aeb533e 282 // MODE_STANDARD 0x00
IanBenzMaxim 21:00c94aeb533e 283 //
IanBenzMaxim 21:00c94aeb533e 284 // Returns: current 1-Wire Net level
IanBenzMaxim 21:00c94aeb533e 285 //
IanBenzMaxim 32:bce180b544ed 286 OneWireMaster::CmdResult DS2465::OWSetLevel(OWLevel new_level)
IanBenzMaxim 21:00c94aeb533e 287 {
IanBenzMaxim 32:bce180b544ed 288 if (new_level == LEVEL_STRONG)
IanBenzMaxim 27:d5aaefa252f1 289 return OneWireMaster::OperationFailure;
IanBenzMaxim 27:d5aaefa252f1 290
IanBenzMaxim 32:bce180b544ed 291 return ConfigureLevel(new_level);
IanBenzMaxim 21:00c94aeb533e 292 }
IanBenzMaxim 21:00c94aeb533e 293
IanBenzMaxim 21:00c94aeb533e 294 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 295 // Set the 1-Wire Net communication speed.
IanBenzMaxim 21:00c94aeb533e 296 //
IanBenzMaxim 21:00c94aeb533e 297 // 'new_speed' - new speed defined as
IanBenzMaxim 21:00c94aeb533e 298 // MODE_STANDARD 0x00
IanBenzMaxim 21:00c94aeb533e 299 // MODE_OVERDRIVE 0x01
IanBenzMaxim 21:00c94aeb533e 300 //
IanBenzMaxim 21:00c94aeb533e 301 // Returns: current 1-Wire Net speed
IanBenzMaxim 21:00c94aeb533e 302 //
IanBenzMaxim 32:bce180b544ed 303 OneWireMaster::CmdResult DS2465::OWSetSpeed(OWSpeed new_speed)
IanBenzMaxim 21:00c94aeb533e 304 {
IanBenzMaxim 27:d5aaefa252f1 305 // Requested speed is already set
IanBenzMaxim 27:d5aaefa252f1 306 if (m_curConfig.c1WS == (new_speed == SPEED_OVERDRIVE))
IanBenzMaxim 27:d5aaefa252f1 307 return OneWireMaster::Success;
IanBenzMaxim 27:d5aaefa252f1 308
IanBenzMaxim 27:d5aaefa252f1 309 // set the speed
IanBenzMaxim 27:d5aaefa252f1 310 m_curConfig.c1WS = (new_speed == SPEED_OVERDRIVE);
IanBenzMaxim 21:00c94aeb533e 311
IanBenzMaxim 27:d5aaefa252f1 312 // write the new config
IanBenzMaxim 27:d5aaefa252f1 313 return WriteConfig(m_curConfig);
IanBenzMaxim 21:00c94aeb533e 314 }
IanBenzMaxim 21:00c94aeb533e 315
IanBenzMaxim 21:00c94aeb533e 316 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 317 // Use the DS2465 help command '1-Wire triplet' to perform one bit of a 1-Wire
IanBenzMaxim 21:00c94aeb533e 318 // search. This command does two read bits and one write bit. The write bit
IanBenzMaxim 21:00c94aeb533e 319 // is either the default direction (all device have same bit) or in case of
IanBenzMaxim 21:00c94aeb533e 320 // a discripancy, the 'search_direction' parameter is used.
IanBenzMaxim 21:00c94aeb533e 321 //
j3 22:686273e55cdc 322 // Returns � The DS2465 status byte result from the triplet command
IanBenzMaxim 21:00c94aeb533e 323 //
IanBenzMaxim 32:bce180b544ed 324 OneWireMaster::CmdResult DS2465::OWTriplet(SearchDirection & search_direction, std::uint8_t & sbr, std::uint8_t & tsb)
IanBenzMaxim 21:00c94aeb533e 325 {
IanBenzMaxim 21:00c94aeb533e 326 // 1-Wire Triplet (Case B)
IanBenzMaxim 21:00c94aeb533e 327 // S AD,0 [A] 1WT [A] SS [A] Sr AD,1 [A] [Status] A [Status] A\ P
IanBenzMaxim 21:00c94aeb533e 328 // \--------/
IanBenzMaxim 21:00c94aeb533e 329 // Repeat until 1WB bit has changed to 0
IanBenzMaxim 21:00c94aeb533e 330 // [] indicates from slave
IanBenzMaxim 21:00c94aeb533e 331 // SS indicates byte containing search direction bit value in msbit
IanBenzMaxim 24:8942d8478d68 332
IanBenzMaxim 24:8942d8478d68 333 OneWireMaster::CmdResult result;
IanBenzMaxim 27:d5aaefa252f1 334 std::uint8_t command[2] = { CMD_1WT, ((search_direction == DIRECTION_WRITE_ONE) ? 0x80 : 0x00) };
IanBenzMaxim 24:8942d8478d68 335 result = WriteMemory(ADDR_CMD_REG, command, 2);
IanBenzMaxim 24:8942d8478d68 336 if (result == OneWireMaster::Success)
IanBenzMaxim 32:bce180b544ed 337 {
IanBenzMaxim 32:bce180b544ed 338 std::uint8_t status;
IanBenzMaxim 24:8942d8478d68 339 result = PollBusy(&status);
IanBenzMaxim 32:bce180b544ed 340 if (result == OneWireMaster::Success)
IanBenzMaxim 32:bce180b544ed 341 {
IanBenzMaxim 32:bce180b544ed 342 // check bit results in status byte
IanBenzMaxim 32:bce180b544ed 343 sbr = ((status & STATUS_SBR) == STATUS_SBR);
IanBenzMaxim 32:bce180b544ed 344 tsb = ((status & STATUS_TSB) == STATUS_TSB);
IanBenzMaxim 32:bce180b544ed 345 search_direction = ((status & STATUS_DIR) == STATUS_DIR) ? DIRECTION_WRITE_ONE : DIRECTION_WRITE_ZERO;
IanBenzMaxim 32:bce180b544ed 346 }
IanBenzMaxim 32:bce180b544ed 347 }
IanBenzMaxim 24:8942d8478d68 348 return result;
IanBenzMaxim 21:00c94aeb533e 349 }
IanBenzMaxim 21:00c94aeb533e 350
IanBenzMaxim 21:00c94aeb533e 351 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 352 // The 'OWReadBlock' receives a block of data from the
IanBenzMaxim 21:00c94aeb533e 353 // 1-Wire Net. The destination is the mac buffer (rx_mac=1) or
IanBenzMaxim 21:00c94aeb533e 354 // the scratchpad (rx_mac=0). The result is buffer is returned.
IanBenzMaxim 21:00c94aeb533e 355 //
IanBenzMaxim 21:00c94aeb533e 356 // 'rx_buf' - pointer to a block to receive bytes
IanBenzMaxim 21:00c94aeb533e 357 // of length 'rx_len' from 1-Wire Net
IanBenzMaxim 21:00c94aeb533e 358 // 'rx_len' - length in bytes to read. Only valid numbers are 8,16,20,32;
IanBenzMaxim 21:00c94aeb533e 359 //
IanBenzMaxim 27:d5aaefa252f1 360 OneWireMaster::CmdResult DS2465::OWReadBlock(std::uint8_t *rx_buf, std::uint8_t rx_len)
IanBenzMaxim 21:00c94aeb533e 361 {
IanBenzMaxim 21:00c94aeb533e 362 // 1-Wire Receive Block (Case A)
IanBenzMaxim 21:00c94aeb533e 363 // S AD,0 [A] ADDR_CMD_REG [A] 1WRF [A] PR [A] P
IanBenzMaxim 21:00c94aeb533e 364 // [] indicates from slave
IanBenzMaxim 21:00c94aeb533e 365 // PR indicates byte containing parameter
IanBenzMaxim 21:00c94aeb533e 366
IanBenzMaxim 24:8942d8478d68 367 OneWireMaster::CmdResult result;
IanBenzMaxim 27:d5aaefa252f1 368 std::uint8_t command[2] = { CMD_1WRF, rx_len };
IanBenzMaxim 24:8942d8478d68 369
IanBenzMaxim 24:8942d8478d68 370 result = WriteMemory(ADDR_CMD_REG, command, 2);
IanBenzMaxim 24:8942d8478d68 371 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 372 result = PollBusy();
IanBenzMaxim 24:8942d8478d68 373 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 374 result = ReadMemory(ADDR_SPAD, rx_buf, rx_len, false);
IanBenzMaxim 21:00c94aeb533e 375
IanBenzMaxim 24:8942d8478d68 376 return result;
IanBenzMaxim 21:00c94aeb533e 377 }
IanBenzMaxim 21:00c94aeb533e 378
IanBenzMaxim 21:00c94aeb533e 379
IanBenzMaxim 21:00c94aeb533e 380
IanBenzMaxim 21:00c94aeb533e 381
IanBenzMaxim 27:d5aaefa252f1 382 OneWireMaster::CmdResult DS2465::OWWriteBlock(const std::uint8_t *tran_buf, std::uint8_t tran_len)
IanBenzMaxim 21:00c94aeb533e 383 {
IanBenzMaxim 21:00c94aeb533e 384 return OWWriteBlock(false, tran_buf, tran_len);
IanBenzMaxim 21:00c94aeb533e 385 }
IanBenzMaxim 21:00c94aeb533e 386
IanBenzMaxim 21:00c94aeb533e 387 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 388 // The 'OWWriteBlock' transfers a block of data to the
IanBenzMaxim 21:00c94aeb533e 389 // 1-Wire Net. The mac buffer can be sent (tx_mac=1) or a
IanBenzMaxim 21:00c94aeb533e 390 // portion of the scratchpad can be sent.
IanBenzMaxim 21:00c94aeb533e 391 //
IanBenzMaxim 21:00c94aeb533e 392 // 'tx_mac' - flag to indicate if the MAC buffer is to be sent (1) or
IanBenzMaxim 21:00c94aeb533e 393 // the data provided in teh tran_buf is to be sent (0)
IanBenzMaxim 21:00c94aeb533e 394 // 'tran_buf' - pointer to a block of bytes
IanBenzMaxim 21:00c94aeb533e 395 // of length 'tran_len' that will be sent
IanBenzMaxim 21:00c94aeb533e 396 // to the 1-Wire Net
IanBenzMaxim 21:00c94aeb533e 397 // 'tran_len' - length in bytes to transfer. Only valid numbers are 8,16,20,32;
IanBenzMaxim 21:00c94aeb533e 398 //
IanBenzMaxim 27:d5aaefa252f1 399 OneWireMaster::CmdResult DS2465::OWWriteBlock(bool tx_mac, const std::uint8_t *tran_buf, std::uint8_t tran_len)
IanBenzMaxim 21:00c94aeb533e 400 {
IanBenzMaxim 21:00c94aeb533e 401 OneWireMaster::CmdResult result;
IanBenzMaxim 27:d5aaefa252f1 402 std::uint8_t command[2] = { CMD_1WTB, (tx_mac ? 0xFF : tran_len) };
IanBenzMaxim 21:00c94aeb533e 403
IanBenzMaxim 24:8942d8478d68 404 if (!tx_mac)
IanBenzMaxim 21:00c94aeb533e 405 {
IanBenzMaxim 21:00c94aeb533e 406 // prefill scratchpad with required data
IanBenzMaxim 24:8942d8478d68 407 result = WriteMemory(ADDR_SPAD, tran_buf, tran_len);
IanBenzMaxim 21:00c94aeb533e 408 if (result != OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 409 return result;
IanBenzMaxim 21:00c94aeb533e 410 }
IanBenzMaxim 21:00c94aeb533e 411
IanBenzMaxim 21:00c94aeb533e 412 // 1-Wire Transmit Block (Case A)
IanBenzMaxim 21:00c94aeb533e 413 // S AD,0 [A] ADDR_CMD_REG [A] 1WTB [A] PR [A] P
IanBenzMaxim 21:00c94aeb533e 414 // [] indicates from slave
IanBenzMaxim 21:00c94aeb533e 415 // PR indicates byte containing parameter
IanBenzMaxim 24:8942d8478d68 416
IanBenzMaxim 24:8942d8478d68 417 result = WriteMemory(ADDR_CMD_REG, command, 2);
IanBenzMaxim 24:8942d8478d68 418
IanBenzMaxim 24:8942d8478d68 419 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 420 result = PollBusy();
IanBenzMaxim 21:00c94aeb533e 421
IanBenzMaxim 24:8942d8478d68 422 return result;
IanBenzMaxim 21:00c94aeb533e 423 }
IanBenzMaxim 21:00c94aeb533e 424
IanBenzMaxim 21:00c94aeb533e 425 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 426 // Send 8 bits of read communication to the 1-Wire Net and return the
IanBenzMaxim 21:00c94aeb533e 427 // result 8 bits read from the 1-Wire Net.
IanBenzMaxim 21:00c94aeb533e 428 //
IanBenzMaxim 21:00c94aeb533e 429 // Returns: 8 bits read from 1-Wire Net
IanBenzMaxim 21:00c94aeb533e 430 //
IanBenzMaxim 32:bce180b544ed 431 OneWireMaster::CmdResult DS2465::OWReadByte(std::uint8_t & recvbyte, OWLevel after_level)
IanBenzMaxim 21:00c94aeb533e 432 {
IanBenzMaxim 24:8942d8478d68 433 OneWireMaster::CmdResult result;
IanBenzMaxim 27:d5aaefa252f1 434 std::uint8_t buf;
IanBenzMaxim 21:00c94aeb533e 435
IanBenzMaxim 24:8942d8478d68 436 // 1-Wire Read Bytes (Case C)
IanBenzMaxim 24:8942d8478d68 437 // S AD,0 [A] ADDR_CMD_REG [A] 1WRB [A] Sr AD,1 [A] [Status] A [Status] A
IanBenzMaxim 24:8942d8478d68 438 // \--------/
IanBenzMaxim 24:8942d8478d68 439 // Repeat until 1WB bit has changed to 0
IanBenzMaxim 24:8942d8478d68 440 // Sr AD,0 [A] SRP [A] E1 [A] Sr AD,1 [A] DD A\ P
IanBenzMaxim 24:8942d8478d68 441 //
IanBenzMaxim 24:8942d8478d68 442 // [] indicates from slave
IanBenzMaxim 24:8942d8478d68 443 // DD data read
IanBenzMaxim 26:a361e3f42ba5 444
IanBenzMaxim 32:bce180b544ed 445 result = ConfigureLevel(after_level);
IanBenzMaxim 26:a361e3f42ba5 446 if (result != OneWireMaster::Success)
IanBenzMaxim 26:a361e3f42ba5 447 return result;
IanBenzMaxim 24:8942d8478d68 448
IanBenzMaxim 24:8942d8478d68 449 buf = CMD_1WRB;
IanBenzMaxim 24:8942d8478d68 450 result = WriteMemory(ADDR_CMD_REG, &buf, 1);
IanBenzMaxim 21:00c94aeb533e 451
IanBenzMaxim 24:8942d8478d68 452 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 453 result = PollBusy();
IanBenzMaxim 24:8942d8478d68 454
IanBenzMaxim 24:8942d8478d68 455 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 456 result = ReadMemory(ADDR_DATA_REG, &buf, 1);
IanBenzMaxim 21:00c94aeb533e 457
IanBenzMaxim 24:8942d8478d68 458 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 459 recvbyte = buf;
IanBenzMaxim 21:00c94aeb533e 460
IanBenzMaxim 24:8942d8478d68 461 return result;
IanBenzMaxim 21:00c94aeb533e 462 }
IanBenzMaxim 21:00c94aeb533e 463
IanBenzMaxim 21:00c94aeb533e 464 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 465 // Send 8 bits of communication to the 1-Wire Net and verify that the
IanBenzMaxim 21:00c94aeb533e 466 // 8 bits read from the 1-Wire Net is the same (write operation).
IanBenzMaxim 21:00c94aeb533e 467 // The parameter 'sendbyte' least significant 8 bits are used.
IanBenzMaxim 21:00c94aeb533e 468 //
IanBenzMaxim 21:00c94aeb533e 469 // 'sendbyte' - 8 bits to send (least significant byte)
IanBenzMaxim 21:00c94aeb533e 470 //
IanBenzMaxim 21:00c94aeb533e 471 // Returns: true: bytes written and echo was the same
IanBenzMaxim 21:00c94aeb533e 472 // false: echo was not the same
IanBenzMaxim 21:00c94aeb533e 473 //
IanBenzMaxim 32:bce180b544ed 474 OneWireMaster::CmdResult DS2465::OWWriteByte(std::uint8_t sendbyte, OWLevel after_level)
IanBenzMaxim 24:8942d8478d68 475 {
IanBenzMaxim 21:00c94aeb533e 476 // 1-Wire Write Byte (Case B)
IanBenzMaxim 21:00c94aeb533e 477 // S AD,0 [A] ADDR_CMD_REG [A] 1WWB [A] DD [A] Sr AD,1 [A] [Status] A [Status] A\ P
IanBenzMaxim 21:00c94aeb533e 478 // \--------/
IanBenzMaxim 21:00c94aeb533e 479 // Repeat until 1WB bit has changed to 0
IanBenzMaxim 21:00c94aeb533e 480 // [] indicates from slave
IanBenzMaxim 21:00c94aeb533e 481 // DD data to write
IanBenzMaxim 24:8942d8478d68 482
IanBenzMaxim 24:8942d8478d68 483 OneWireMaster::CmdResult result;
IanBenzMaxim 26:a361e3f42ba5 484
IanBenzMaxim 32:bce180b544ed 485 result = ConfigureLevel(after_level);
IanBenzMaxim 26:a361e3f42ba5 486 if (result != OneWireMaster::Success)
IanBenzMaxim 26:a361e3f42ba5 487 return result;
IanBenzMaxim 26:a361e3f42ba5 488
IanBenzMaxim 27:d5aaefa252f1 489 std::uint8_t command[2] = { CMD_1WWB, sendbyte };
IanBenzMaxim 24:8942d8478d68 490
IanBenzMaxim 24:8942d8478d68 491 result = WriteMemory(ADDR_CMD_REG, command, 2);
IanBenzMaxim 24:8942d8478d68 492 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 493 result = PollBusy();
IanBenzMaxim 21:00c94aeb533e 494
IanBenzMaxim 24:8942d8478d68 495 return result;
IanBenzMaxim 21:00c94aeb533e 496 }
IanBenzMaxim 21:00c94aeb533e 497
IanBenzMaxim 21:00c94aeb533e 498 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 499 // Send 1 bit of communication to the 1-Wire Net and return the
IanBenzMaxim 21:00c94aeb533e 500 // result 1 bit read from the 1-Wire Net. The parameter 'sendbit'
IanBenzMaxim 21:00c94aeb533e 501 // least significant bit is used and the least significant bit
IanBenzMaxim 21:00c94aeb533e 502 // of the result is the return bit.
IanBenzMaxim 21:00c94aeb533e 503 //
IanBenzMaxim 21:00c94aeb533e 504 // 'sendbit' - the least significant bit is the bit to send
IanBenzMaxim 21:00c94aeb533e 505 //
IanBenzMaxim 21:00c94aeb533e 506 // Returns: 0: 0 bit read from sendbit
IanBenzMaxim 21:00c94aeb533e 507 // 1: 1 bit read from sendbit
IanBenzMaxim 21:00c94aeb533e 508 //
IanBenzMaxim 32:bce180b544ed 509 OneWireMaster::CmdResult DS2465::OWTouchBit(std::uint8_t & sendrecvbit, OWLevel after_level)
IanBenzMaxim 21:00c94aeb533e 510 {
IanBenzMaxim 21:00c94aeb533e 511 // 1-Wire bit (Case B)
IanBenzMaxim 21:00c94aeb533e 512 // S AD,0 [A] ADDR_CMD_REG [A] 1WSB [A] BB [A] Sr AD,1 [A] [Status] A [Status] A\ P
IanBenzMaxim 21:00c94aeb533e 513 // \--------/
IanBenzMaxim 21:00c94aeb533e 514 // Repeat until 1WB bit has changed to 0
IanBenzMaxim 21:00c94aeb533e 515 // [] indicates from slave
IanBenzMaxim 21:00c94aeb533e 516 // BB indicates byte containing bit value in msbit
IanBenzMaxim 21:00c94aeb533e 517
IanBenzMaxim 24:8942d8478d68 518 OneWireMaster::CmdResult result;
IanBenzMaxim 26:a361e3f42ba5 519
IanBenzMaxim 32:bce180b544ed 520 result = ConfigureLevel(after_level);
IanBenzMaxim 26:a361e3f42ba5 521 if (result != OneWireMaster::Success)
IanBenzMaxim 26:a361e3f42ba5 522 return result;
IanBenzMaxim 26:a361e3f42ba5 523
IanBenzMaxim 27:d5aaefa252f1 524 std::uint8_t command[2] = { CMD_1WSB, (sendrecvbit ? 0x80 : 0x00) };
IanBenzMaxim 27:d5aaefa252f1 525 std::uint8_t status;
IanBenzMaxim 24:8942d8478d68 526
IanBenzMaxim 24:8942d8478d68 527 result = WriteMemory(ADDR_CMD_REG, command, 2);
IanBenzMaxim 21:00c94aeb533e 528
IanBenzMaxim 24:8942d8478d68 529 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 530 result = PollBusy(&status);
IanBenzMaxim 21:00c94aeb533e 531
IanBenzMaxim 24:8942d8478d68 532 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 533 sendrecvbit = (status & STATUS_SBR);
IanBenzMaxim 24:8942d8478d68 534
IanBenzMaxim 24:8942d8478d68 535 return result;
IanBenzMaxim 21:00c94aeb533e 536 }
IanBenzMaxim 21:00c94aeb533e 537
IanBenzMaxim 21:00c94aeb533e 538 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 539 // Write to Scratchpad (SRAM) memory on the DS2465
IanBenzMaxim 21:00c94aeb533e 540 //
IanBenzMaxim 21:00c94aeb533e 541 // 'addr' - address to start writing (must be in SRAM)
IanBenzMaxim 21:00c94aeb533e 542 // 'buf' - buffer of data to write
IanBenzMaxim 21:00c94aeb533e 543 // 'len' - length to write
IanBenzMaxim 21:00c94aeb533e 544 //
IanBenzMaxim 21:00c94aeb533e 545 // Returns: true write successful
IanBenzMaxim 21:00c94aeb533e 546 // false failure to complete write
IanBenzMaxim 21:00c94aeb533e 547 //
IanBenzMaxim 27:d5aaefa252f1 548 OneWireMaster::CmdResult DS2465::CWriteMemory(std::uint8_t addr, const std::uint8_t * buf, std::size_t bufLen) const
IanBenzMaxim 21:00c94aeb533e 549 {
IanBenzMaxim 21:00c94aeb533e 550 int i;
IanBenzMaxim 21:00c94aeb533e 551
IanBenzMaxim 21:00c94aeb533e 552 // Write SRAM (Case A)
IanBenzMaxim 21:00c94aeb533e 553 // S AD,0 [A] VSA [A] DD [A] P
IanBenzMaxim 21:00c94aeb533e 554 // \-----/
IanBenzMaxim 21:00c94aeb533e 555 // Repeat for each data byte
IanBenzMaxim 21:00c94aeb533e 556 // [] indicates from slave
IanBenzMaxim 21:00c94aeb533e 557 // VSA valid SRAM memory address
IanBenzMaxim 21:00c94aeb533e 558 // DD memory data to write
IanBenzMaxim 21:00c94aeb533e 559
IanBenzMaxim 21:00c94aeb533e 560 m_I2C_interface.start();
IanBenzMaxim 32:bce180b544ed 561 if (m_I2C_interface.write((m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK)
IanBenzMaxim 21:00c94aeb533e 562 {
IanBenzMaxim 21:00c94aeb533e 563 m_I2C_interface.stop();
IanBenzMaxim 21:00c94aeb533e 564 return OneWireMaster::CommunicationWriteError;
IanBenzMaxim 21:00c94aeb533e 565 }
IanBenzMaxim 32:bce180b544ed 566 if (m_I2C_interface.write(addr) != I2C_WRITE_OK)
IanBenzMaxim 21:00c94aeb533e 567 {
IanBenzMaxim 21:00c94aeb533e 568 m_I2C_interface.stop();
IanBenzMaxim 21:00c94aeb533e 569 return OneWireMaster::CommunicationWriteError;
IanBenzMaxim 21:00c94aeb533e 570 }
IanBenzMaxim 21:00c94aeb533e 571 // loop to write each byte
IanBenzMaxim 21:00c94aeb533e 572 for (i = 0; i < bufLen; i++)
IanBenzMaxim 21:00c94aeb533e 573 {
IanBenzMaxim 21:00c94aeb533e 574 if (m_I2C_interface.write(buf[i]) != I2C_WRITE_OK)
IanBenzMaxim 21:00c94aeb533e 575 {
IanBenzMaxim 21:00c94aeb533e 576 m_I2C_interface.stop();
IanBenzMaxim 21:00c94aeb533e 577 return OneWireMaster::CommunicationWriteError;
IanBenzMaxim 21:00c94aeb533e 578 }
IanBenzMaxim 21:00c94aeb533e 579 }
IanBenzMaxim 21:00c94aeb533e 580 m_I2C_interface.stop();
IanBenzMaxim 21:00c94aeb533e 581
IanBenzMaxim 21:00c94aeb533e 582 return OneWireMaster::Success;
IanBenzMaxim 21:00c94aeb533e 583 }
IanBenzMaxim 21:00c94aeb533e 584
IanBenzMaxim 21:00c94aeb533e 585 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 586 // Read memory from the DS2465
IanBenzMaxim 21:00c94aeb533e 587 //
IanBenzMaxim 21:00c94aeb533e 588 // 'addr' - address to start reading
IanBenzMaxim 21:00c94aeb533e 589 // 'buf' - buffer to hold memory read
IanBenzMaxim 21:00c94aeb533e 590 // 'len' - length to read
IanBenzMaxim 21:00c94aeb533e 591 // 'skip_set_pointer' - flag to indicate to skip setting address pointer
IanBenzMaxim 21:00c94aeb533e 592 //
IanBenzMaxim 21:00c94aeb533e 593 // Returns: true read successful
IanBenzMaxim 21:00c94aeb533e 594 // false failure to complete read
IanBenzMaxim 21:00c94aeb533e 595 //
IanBenzMaxim 27:d5aaefa252f1 596 OneWireMaster::CmdResult DS2465::ReadMemory(std::uint8_t addr, std::uint8_t * buf, std::size_t bufLen, bool skip_set_pointer) const
IanBenzMaxim 21:00c94aeb533e 597 {
IanBenzMaxim 21:00c94aeb533e 598 int i;
IanBenzMaxim 21:00c94aeb533e 599
IanBenzMaxim 21:00c94aeb533e 600 // Read (Case A)
IanBenzMaxim 21:00c94aeb533e 601 // S AD,0 [A] MA [A] Sr AD,1 [A] [DD] A [DD] A\ P
IanBenzMaxim 21:00c94aeb533e 602 // \-----/
IanBenzMaxim 21:00c94aeb533e 603 // Repeat for each data byte, NAK last byte
IanBenzMaxim 21:00c94aeb533e 604 // [] indicates from slave
IanBenzMaxim 21:00c94aeb533e 605 // MA memory address
IanBenzMaxim 21:00c94aeb533e 606 // DD memory data read
IanBenzMaxim 21:00c94aeb533e 607
IanBenzMaxim 21:00c94aeb533e 608 m_I2C_interface.start();
IanBenzMaxim 21:00c94aeb533e 609 if (!skip_set_pointer)
IanBenzMaxim 21:00c94aeb533e 610 {
IanBenzMaxim 32:bce180b544ed 611 if (m_I2C_interface.write((m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK)
IanBenzMaxim 21:00c94aeb533e 612 {
IanBenzMaxim 21:00c94aeb533e 613 m_I2C_interface.stop();
IanBenzMaxim 21:00c94aeb533e 614 return OneWireMaster::CommunicationWriteError;
IanBenzMaxim 21:00c94aeb533e 615 }
IanBenzMaxim 32:bce180b544ed 616 if (m_I2C_interface.write(addr) != I2C_WRITE_OK)
IanBenzMaxim 21:00c94aeb533e 617 {
IanBenzMaxim 21:00c94aeb533e 618 m_I2C_interface.stop();
IanBenzMaxim 21:00c94aeb533e 619 return OneWireMaster::CommunicationWriteError;
IanBenzMaxim 21:00c94aeb533e 620 }
IanBenzMaxim 21:00c94aeb533e 621 m_I2C_interface.start();
IanBenzMaxim 21:00c94aeb533e 622 }
IanBenzMaxim 21:00c94aeb533e 623
IanBenzMaxim 32:bce180b544ed 624 if (m_I2C_interface.write((m_I2C_address | I2C_READ)) != I2C_WRITE_OK)
IanBenzMaxim 21:00c94aeb533e 625 {
IanBenzMaxim 21:00c94aeb533e 626 m_I2C_interface.stop();
IanBenzMaxim 21:00c94aeb533e 627 return OneWireMaster::CommunicationWriteError;
IanBenzMaxim 21:00c94aeb533e 628 }
IanBenzMaxim 21:00c94aeb533e 629 // loop to read each byte, NAK last byte
IanBenzMaxim 21:00c94aeb533e 630 for (i = 0; i < bufLen; i++)
IanBenzMaxim 21:00c94aeb533e 631 {
IanBenzMaxim 21:00c94aeb533e 632 buf[i] = m_I2C_interface.read((i == (bufLen - 1)) ? m_I2C_interface.NoACK : m_I2C_interface.ACK);
IanBenzMaxim 21:00c94aeb533e 633 }
IanBenzMaxim 21:00c94aeb533e 634 m_I2C_interface.stop();
IanBenzMaxim 21:00c94aeb533e 635
IanBenzMaxim 21:00c94aeb533e 636 return OneWireMaster::Success;
IanBenzMaxim 21:00c94aeb533e 637 }
IanBenzMaxim 21:00c94aeb533e 638
IanBenzMaxim 21:00c94aeb533e 639 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 640 // Write the configuration register in the DS2465. The configuration
IanBenzMaxim 21:00c94aeb533e 641 // options are provided in the lower nibble of the provided config byte.
IanBenzMaxim 21:00c94aeb533e 642 // The uppper nibble in bitwise inverted when written to the DS2465.
IanBenzMaxim 21:00c94aeb533e 643 //
IanBenzMaxim 21:00c94aeb533e 644 // Returns: true: config written and response correct
IanBenzMaxim 21:00c94aeb533e 645 // false: response incorrect
IanBenzMaxim 21:00c94aeb533e 646 //
IanBenzMaxim 24:8942d8478d68 647 OneWireMaster::CmdResult DS2465::WriteConfig(const Config & config)
IanBenzMaxim 21:00c94aeb533e 648 {
IanBenzMaxim 24:8942d8478d68 649 std::uint8_t configBuf;
IanBenzMaxim 24:8942d8478d68 650 OneWireMaster::CmdResult result;
IanBenzMaxim 21:00c94aeb533e 651
IanBenzMaxim 24:8942d8478d68 652 configBuf = config.writeByte();
IanBenzMaxim 24:8942d8478d68 653 result = WriteMemory(ADDR_WCFG_REG, &configBuf, 1);
IanBenzMaxim 24:8942d8478d68 654 if (result == OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 655 {
IanBenzMaxim 24:8942d8478d68 656 result = ReadMemory(ADDR_WCFG_REG, &configBuf, 1);
IanBenzMaxim 24:8942d8478d68 657 }
IanBenzMaxim 24:8942d8478d68 658 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 659 {
IanBenzMaxim 24:8942d8478d68 660 if (configBuf != config.readByte())
IanBenzMaxim 24:8942d8478d68 661 result = OneWireMaster::OperationFailure;
IanBenzMaxim 21:00c94aeb533e 662 }
IanBenzMaxim 21:00c94aeb533e 663
IanBenzMaxim 24:8942d8478d68 664 return result;
IanBenzMaxim 24:8942d8478d68 665 }
IanBenzMaxim 24:8942d8478d68 666
IanBenzMaxim 24:8942d8478d68 667
IanBenzMaxim 24:8942d8478d68 668
IanBenzMaxim 32:bce180b544ed 669 DS2465::Config DS2465::CurrentConfig() const
IanBenzMaxim 32:bce180b544ed 670 {
IanBenzMaxim 32:bce180b544ed 671 return m_curConfig;
IanBenzMaxim 32:bce180b544ed 672 }
IanBenzMaxim 32:bce180b544ed 673
IanBenzMaxim 32:bce180b544ed 674
IanBenzMaxim 32:bce180b544ed 675
IanBenzMaxim 24:8942d8478d68 676
IanBenzMaxim 27:d5aaefa252f1 677 OneWireMaster::CmdResult DS2465::PollBusy(std::uint8_t * pStatus)
IanBenzMaxim 24:8942d8478d68 678 {
IanBenzMaxim 24:8942d8478d68 679 const unsigned int pollLimit = 200;
IanBenzMaxim 24:8942d8478d68 680
IanBenzMaxim 24:8942d8478d68 681 OneWireMaster::CmdResult result;
IanBenzMaxim 27:d5aaefa252f1 682 std::uint8_t status;
IanBenzMaxim 24:8942d8478d68 683 unsigned int pollCount = 0;
IanBenzMaxim 24:8942d8478d68 684
IanBenzMaxim 24:8942d8478d68 685 // loop checking 1WB bit for completion of 1-Wire operation
IanBenzMaxim 24:8942d8478d68 686 // abort if poll limit reached
IanBenzMaxim 24:8942d8478d68 687
IanBenzMaxim 24:8942d8478d68 688 do
IanBenzMaxim 24:8942d8478d68 689 {
IanBenzMaxim 24:8942d8478d68 690 result = ReadMemory(ADDR_STATUS_REG, &status, 1, true);
IanBenzMaxim 24:8942d8478d68 691 if (result != OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 692 return result;
IanBenzMaxim 24:8942d8478d68 693 if (pStatus != NULL)
IanBenzMaxim 24:8942d8478d68 694 *pStatus = status;
IanBenzMaxim 24:8942d8478d68 695 if (pollCount++ >= pollLimit)
IanBenzMaxim 24:8942d8478d68 696 return OneWireMaster::TimeoutError;
IanBenzMaxim 24:8942d8478d68 697 } while (status & STATUS_1WB);
IanBenzMaxim 24:8942d8478d68 698
IanBenzMaxim 21:00c94aeb533e 699 return OneWireMaster::Success;
IanBenzMaxim 21:00c94aeb533e 700 }
IanBenzMaxim 21:00c94aeb533e 701
IanBenzMaxim 21:00c94aeb533e 702 //--------------------------------------------------------------------------
IanBenzMaxim 21:00c94aeb533e 703 // Reset all of the devices on the 1-Wire Net and return the result.
IanBenzMaxim 21:00c94aeb533e 704 //
IanBenzMaxim 21:00c94aeb533e 705 // Returns: true(1): presense pulse(s) detected, device(s) reset
IanBenzMaxim 21:00c94aeb533e 706 // false(0): no presense pulses detected
IanBenzMaxim 21:00c94aeb533e 707 //
IanBenzMaxim 21:00c94aeb533e 708 OneWireMaster::CmdResult DS2465::OWReset(void)
IanBenzMaxim 24:8942d8478d68 709 {
IanBenzMaxim 24:8942d8478d68 710 // 1-Wire reset (Case B)
IanBenzMaxim 24:8942d8478d68 711 // S AD,0 [A] ADDR_CMD_REG [A] 1WRS [A] Sr AD,1 [A] [Status] A [Status] A\ P
IanBenzMaxim 24:8942d8478d68 712 // \--------/
IanBenzMaxim 24:8942d8478d68 713 // Repeat until 1WB bit has changed to 0
IanBenzMaxim 24:8942d8478d68 714 // [] indicates from slave
IanBenzMaxim 21:00c94aeb533e 715
IanBenzMaxim 24:8942d8478d68 716 OneWireMaster::CmdResult result;
IanBenzMaxim 27:d5aaefa252f1 717 std::uint8_t buf;
IanBenzMaxim 21:00c94aeb533e 718
IanBenzMaxim 24:8942d8478d68 719 buf = CMD_1WRS;
IanBenzMaxim 24:8942d8478d68 720 result = WriteMemory(ADDR_CMD_REG, &buf, 1);
IanBenzMaxim 21:00c94aeb533e 721
IanBenzMaxim 24:8942d8478d68 722 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 723 result = PollBusy(&buf);
IanBenzMaxim 24:8942d8478d68 724
IanBenzMaxim 24:8942d8478d68 725 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 726 {
IanBenzMaxim 24:8942d8478d68 727 // check for presence detect
IanBenzMaxim 24:8942d8478d68 728 if ((buf & STATUS_PPD) != STATUS_PPD)
IanBenzMaxim 24:8942d8478d68 729 result = OneWireMaster::OperationFailure;
IanBenzMaxim 24:8942d8478d68 730 }
IanBenzMaxim 21:00c94aeb533e 731
IanBenzMaxim 24:8942d8478d68 732 return result;
IanBenzMaxim 21:00c94aeb533e 733 }
IanBenzMaxim 21:00c94aeb533e 734
IanBenzMaxim 21:00c94aeb533e 735 OneWireMaster::CmdResult DS2465::Reset(void)
IanBenzMaxim 24:8942d8478d68 736 {
IanBenzMaxim 21:00c94aeb533e 737 // Device Reset
IanBenzMaxim 21:00c94aeb533e 738 // S AD,0 [A] ADDR_CMD_REG [A] 1WMR [A] Sr AD,1 [A] [SS] A\ P
IanBenzMaxim 21:00c94aeb533e 739 // [] indicates from slave
IanBenzMaxim 21:00c94aeb533e 740 // SS status byte to read to verify state
IanBenzMaxim 21:00c94aeb533e 741
IanBenzMaxim 24:8942d8478d68 742 OneWireMaster::CmdResult result;
IanBenzMaxim 27:d5aaefa252f1 743 std::uint8_t buf;
IanBenzMaxim 21:00c94aeb533e 744
IanBenzMaxim 24:8942d8478d68 745 buf = CMD_1WMR;
IanBenzMaxim 24:8942d8478d68 746 result = WriteMemory(ADDR_CMD_REG, &buf, 1);
IanBenzMaxim 21:00c94aeb533e 747
IanBenzMaxim 24:8942d8478d68 748 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 749 result = ReadMemory(ADDR_STATUS_REG, &buf, 1, true);
IanBenzMaxim 24:8942d8478d68 750
IanBenzMaxim 24:8942d8478d68 751 if (result == OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 752 {
IanBenzMaxim 24:8942d8478d68 753 if ((buf & 0xF7) != 0x10)
IanBenzMaxim 24:8942d8478d68 754 result = OneWireMaster::OperationFailure;
IanBenzMaxim 21:00c94aeb533e 755 }
IanBenzMaxim 24:8942d8478d68 756
IanBenzMaxim 24:8942d8478d68 757 if (result == OneWireMaster::Success)
IanBenzMaxim 24:8942d8478d68 758 OWReset(); // do a command to get 1-Wire master reset out of holding state
IanBenzMaxim 21:00c94aeb533e 759
IanBenzMaxim 24:8942d8478d68 760 return result;
IanBenzMaxim 21:00c94aeb533e 761 }
IanBenzMaxim 21:00c94aeb533e 762
IanBenzMaxim 21:00c94aeb533e 763 OneWireMaster::CmdResult DS2465::Detect(void)
IanBenzMaxim 21:00c94aeb533e 764 {
IanBenzMaxim 21:00c94aeb533e 765 OneWireMaster::CmdResult result;
IanBenzMaxim 21:00c94aeb533e 766
IanBenzMaxim 21:00c94aeb533e 767 // reset DS2465
IanBenzMaxim 21:00c94aeb533e 768 result = Reset();
IanBenzMaxim 21:00c94aeb533e 769 if (result != OneWireMaster::Success)
IanBenzMaxim 21:00c94aeb533e 770 return result;
IanBenzMaxim 21:00c94aeb533e 771
IanBenzMaxim 21:00c94aeb533e 772 // default configuration
IanBenzMaxim 24:8942d8478d68 773 m_curConfig.reset();
IanBenzMaxim 21:00c94aeb533e 774
IanBenzMaxim 21:00c94aeb533e 775 // write the default configuration setup
IanBenzMaxim 24:8942d8478d68 776 result = WriteConfig(m_curConfig);
IanBenzMaxim 21:00c94aeb533e 777 return result;
IanBenzMaxim 21:00c94aeb533e 778 }