Implementation of 1-Wire with added Alarm Search Functionality
Dependents: Max32630_One_Wire_Interface
OneWire_Masters/DS2465/DS2465.cpp@26:a361e3f42ba5, 2016-03-23 (annotated)
- Committer:
- IanBenzMaxim
- Date:
- Wed Mar 23 15:25:40 2016 -0500
- Revision:
- 26:a361e3f42ba5
- Parent:
- 24:8942d8478d68
- Child:
- 27:d5aaefa252f1
Rework the OneWireMaster virtual interface for simplicity.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
IanBenzMaxim | 21:00c94aeb533e | 1 | #include "DS2465.hpp" |
IanBenzMaxim | 21:00c94aeb533e | 2 | |
IanBenzMaxim | 21:00c94aeb533e | 3 | #define I2C_WRITE 0 |
IanBenzMaxim | 21:00c94aeb533e | 4 | #define I2C_READ 1 |
IanBenzMaxim | 21:00c94aeb533e | 5 | |
IanBenzMaxim | 21:00c94aeb533e | 6 | // DS2465 commands |
IanBenzMaxim | 21:00c94aeb533e | 7 | #define CMD_1WMR 0xF0 |
IanBenzMaxim | 21:00c94aeb533e | 8 | #define CMD_WCFG 0xD2 |
IanBenzMaxim | 21:00c94aeb533e | 9 | #define CMD_CHSL 0xC3 |
IanBenzMaxim | 21:00c94aeb533e | 10 | #define CMD_SRP 0xE1 |
IanBenzMaxim | 21:00c94aeb533e | 11 | |
IanBenzMaxim | 21:00c94aeb533e | 12 | #define CMD_1WRS 0xB4 |
IanBenzMaxim | 21:00c94aeb533e | 13 | #define CMD_1WWB 0xA5 |
IanBenzMaxim | 21:00c94aeb533e | 14 | #define CMD_1WRB 0x96 |
IanBenzMaxim | 21:00c94aeb533e | 15 | #define CMD_1WSB 0x87 |
IanBenzMaxim | 21:00c94aeb533e | 16 | #define CMD_1WT 0x78 |
IanBenzMaxim | 21:00c94aeb533e | 17 | #define CMD_1WTB 0x69 |
IanBenzMaxim | 21:00c94aeb533e | 18 | #define CMD_1WRF 0xE1 |
IanBenzMaxim | 21:00c94aeb533e | 19 | #define CMD_CPS 0x5A |
IanBenzMaxim | 21:00c94aeb533e | 20 | #define CMD_CSS 0x4B |
IanBenzMaxim | 21:00c94aeb533e | 21 | #define CMD_CSAM 0x3C |
IanBenzMaxim | 21:00c94aeb533e | 22 | #define CMD_CSWM 0x2D |
IanBenzMaxim | 21:00c94aeb533e | 23 | #define CMD_CNMS 0x1E |
IanBenzMaxim | 21:00c94aeb533e | 24 | #define CMD_SPR 0x0F |
IanBenzMaxim | 21:00c94aeb533e | 25 | |
IanBenzMaxim | 21:00c94aeb533e | 26 | // DS2465 status bits |
IanBenzMaxim | 21:00c94aeb533e | 27 | #define STATUS_1WB 0x01 |
IanBenzMaxim | 21:00c94aeb533e | 28 | #define STATUS_PPD 0x02 |
IanBenzMaxim | 21:00c94aeb533e | 29 | #define STATUS_SD 0x04 |
IanBenzMaxim | 21:00c94aeb533e | 30 | #define STATUS_LL 0x08 |
IanBenzMaxim | 21:00c94aeb533e | 31 | #define STATUS_RST 0x10 |
IanBenzMaxim | 21:00c94aeb533e | 32 | #define STATUS_SBR 0x20 |
IanBenzMaxim | 21:00c94aeb533e | 33 | #define STATUS_TSB 0x40 |
IanBenzMaxim | 21:00c94aeb533e | 34 | #define STATUS_DIR 0x80 |
IanBenzMaxim | 21:00c94aeb533e | 35 | |
IanBenzMaxim | 21:00c94aeb533e | 36 | // delays (if not polling for complete) |
IanBenzMaxim | 21:00c94aeb533e | 37 | #define EEPROM_WRITE_DELAY 30 |
IanBenzMaxim | 21:00c94aeb533e | 38 | #define LOAD_SECRET_DELAY 90 |
IanBenzMaxim | 21:00c94aeb533e | 39 | #define SHA_COMPUTATION_DELAY 5 |
IanBenzMaxim | 21:00c94aeb533e | 40 | |
IanBenzMaxim | 21:00c94aeb533e | 41 | static const int I2C_WRITE_OK = 0; |
IanBenzMaxim | 21:00c94aeb533e | 42 | |
IanBenzMaxim | 24:8942d8478d68 | 43 | |
IanBenzMaxim | 24:8942d8478d68 | 44 | std::uint8_t DS2465::Config::readByte() const |
IanBenzMaxim | 24:8942d8478d68 | 45 | { |
IanBenzMaxim | 24:8942d8478d68 | 46 | std::uint8_t config = 0; |
IanBenzMaxim | 24:8942d8478d68 | 47 | if (c1WS) |
IanBenzMaxim | 24:8942d8478d68 | 48 | config |= 0x08; |
IanBenzMaxim | 24:8942d8478d68 | 49 | if (cSPU) |
IanBenzMaxim | 24:8942d8478d68 | 50 | config |= 0x04; |
IanBenzMaxim | 24:8942d8478d68 | 51 | if (cPDN) |
IanBenzMaxim | 24:8942d8478d68 | 52 | config |= 0x02; |
IanBenzMaxim | 24:8942d8478d68 | 53 | if (cAPU) |
IanBenzMaxim | 24:8942d8478d68 | 54 | config |= 0x01; |
IanBenzMaxim | 24:8942d8478d68 | 55 | return config; |
IanBenzMaxim | 24:8942d8478d68 | 56 | } |
IanBenzMaxim | 24:8942d8478d68 | 57 | |
IanBenzMaxim | 24:8942d8478d68 | 58 | std::uint8_t DS2465::Config::writeByte() const |
IanBenzMaxim | 24:8942d8478d68 | 59 | { |
IanBenzMaxim | 24:8942d8478d68 | 60 | std::uint8_t config = readByte(); |
IanBenzMaxim | 24:8942d8478d68 | 61 | return ((~config << 4) | config); |
IanBenzMaxim | 24:8942d8478d68 | 62 | } |
IanBenzMaxim | 24:8942d8478d68 | 63 | |
IanBenzMaxim | 24:8942d8478d68 | 64 | void DS2465::Config::reset() |
IanBenzMaxim | 24:8942d8478d68 | 65 | { |
IanBenzMaxim | 24:8942d8478d68 | 66 | c1WS = cSPU = cPDN = false; |
IanBenzMaxim | 24:8942d8478d68 | 67 | cAPU = true; |
IanBenzMaxim | 24:8942d8478d68 | 68 | } |
IanBenzMaxim | 24:8942d8478d68 | 69 | |
IanBenzMaxim | 24:8942d8478d68 | 70 | |
IanBenzMaxim | 24:8942d8478d68 | 71 | |
IanBenzMaxim | 24:8942d8478d68 | 72 | |
IanBenzMaxim | 21:00c94aeb533e | 73 | DS2465::DS2465(I2C & I2C_interface, unsigned char I2C_address) |
IanBenzMaxim | 21:00c94aeb533e | 74 | : m_I2C_interface(I2C_interface), m_I2C_address(I2C_address) |
IanBenzMaxim | 21:00c94aeb533e | 75 | { |
IanBenzMaxim | 21:00c94aeb533e | 76 | |
IanBenzMaxim | 21:00c94aeb533e | 77 | } |
IanBenzMaxim | 21:00c94aeb533e | 78 | |
IanBenzMaxim | 21:00c94aeb533e | 79 | |
IanBenzMaxim | 21:00c94aeb533e | 80 | |
IanBenzMaxim | 21:00c94aeb533e | 81 | |
IanBenzMaxim | 21:00c94aeb533e | 82 | OneWireMaster::CmdResult DS2465::OWInitMaster() |
IanBenzMaxim | 21:00c94aeb533e | 83 | { |
IanBenzMaxim | 21:00c94aeb533e | 84 | return Detect(); |
IanBenzMaxim | 21:00c94aeb533e | 85 | } |
IanBenzMaxim | 21:00c94aeb533e | 86 | |
IanBenzMaxim | 21:00c94aeb533e | 87 | |
IanBenzMaxim | 21:00c94aeb533e | 88 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 89 | // Compute Next Master Secret DS2465 |
IanBenzMaxim | 21:00c94aeb533e | 90 | // |
IanBenzMaxim | 21:00c94aeb533e | 91 | // 'swap' - 1 if swapping a page into the computation |
IanBenzMaxim | 21:00c94aeb533e | 92 | // 'page' - page number to swap in |
IanBenzMaxim | 21:00c94aeb533e | 93 | // 'region' - (1) first 1/2 page, (2) second 1/2 page, (3) entire page |
IanBenzMaxim | 21:00c94aeb533e | 94 | // |
IanBenzMaxim | 21:00c94aeb533e | 95 | // Returns: true write successful |
IanBenzMaxim | 21:00c94aeb533e | 96 | // false failure to complete read |
IanBenzMaxim | 21:00c94aeb533e | 97 | // |
IanBenzMaxim | 21:00c94aeb533e | 98 | OneWireMaster::CmdResult DS2465::Compute_NextMasterSecret(bool swap, unsigned int pageNum, PageRegion region) |
IanBenzMaxim | 21:00c94aeb533e | 99 | { |
IanBenzMaxim | 24:8942d8478d68 | 100 | uint8_t command[2] = { CMD_CNMS, (swap ? (0xC8 | (pageNum << 4) | region) : 0xBF) }; |
IanBenzMaxim | 24:8942d8478d68 | 101 | return WriteMemory(ADDR_CMD_REG, command, 2); |
IanBenzMaxim | 21:00c94aeb533e | 102 | } |
IanBenzMaxim | 21:00c94aeb533e | 103 | |
IanBenzMaxim | 21:00c94aeb533e | 104 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 105 | // Compute Write MAC DS2465 |
IanBenzMaxim | 21:00c94aeb533e | 106 | // |
IanBenzMaxim | 21:00c94aeb533e | 107 | // 'regwrite' - true if writing to a register, false if regular memory |
IanBenzMaxim | 21:00c94aeb533e | 108 | // 'swap' - true if swapping a page into the computation |
IanBenzMaxim | 21:00c94aeb533e | 109 | // 'page' - page number to swap in |
IanBenzMaxim | 21:00c94aeb533e | 110 | // 'segment' - segment number if swaping |
IanBenzMaxim | 21:00c94aeb533e | 111 | // |
IanBenzMaxim | 21:00c94aeb533e | 112 | // Returns: true write successful |
IanBenzMaxim | 21:00c94aeb533e | 113 | // false failure to complete read |
IanBenzMaxim | 21:00c94aeb533e | 114 | // |
IanBenzMaxim | 21:00c94aeb533e | 115 | OneWireMaster::CmdResult DS2465::Compute_WriteMAC(bool regwrite, bool swap, unsigned int pageNum, unsigned int segmentNum) const |
IanBenzMaxim | 21:00c94aeb533e | 116 | { |
IanBenzMaxim | 24:8942d8478d68 | 117 | uint8_t command[2] = { CMD_CSWM, ((regwrite << 7) | (swap << 6) | (pageNum << 4) | segmentNum) }; |
IanBenzMaxim | 24:8942d8478d68 | 118 | return CWriteMemory(ADDR_CMD_REG, command, 2); |
IanBenzMaxim | 21:00c94aeb533e | 119 | } |
IanBenzMaxim | 21:00c94aeb533e | 120 | |
IanBenzMaxim | 21:00c94aeb533e | 121 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 122 | // Compute Slave Authentication MAC DS2465 |
IanBenzMaxim | 21:00c94aeb533e | 123 | // |
IanBenzMaxim | 21:00c94aeb533e | 124 | // 'swap' - true if swapping a page into the computation |
IanBenzMaxim | 21:00c94aeb533e | 125 | // 'page' - page number to swap in |
IanBenzMaxim | 21:00c94aeb533e | 126 | // 'region' - (1) first 1/2 page, (2) second 1/2 page, (3) entire page |
IanBenzMaxim | 21:00c94aeb533e | 127 | // |
IanBenzMaxim | 21:00c94aeb533e | 128 | // Returns: true write successful |
IanBenzMaxim | 21:00c94aeb533e | 129 | // false failure to complete read |
IanBenzMaxim | 21:00c94aeb533e | 130 | // |
IanBenzMaxim | 21:00c94aeb533e | 131 | OneWireMaster::CmdResult DS2465::Compute_AuthMAC(bool swap, unsigned int pageNum, PageRegion region) const |
IanBenzMaxim | 21:00c94aeb533e | 132 | { |
IanBenzMaxim | 24:8942d8478d68 | 133 | uint8_t command[2] = { CMD_CSAM, (swap ? (0xC8 | (pageNum << 4) | region) : 0xBF) }; |
IanBenzMaxim | 24:8942d8478d68 | 134 | return CWriteMemory(ADDR_CMD_REG, command, 2); |
IanBenzMaxim | 21:00c94aeb533e | 135 | } |
IanBenzMaxim | 21:00c94aeb533e | 136 | |
IanBenzMaxim | 21:00c94aeb533e | 137 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 138 | // Compute S-Secret on DS2465 |
IanBenzMaxim | 21:00c94aeb533e | 139 | // |
IanBenzMaxim | 21:00c94aeb533e | 140 | // 'swap' - true if swapping a page into the computation |
IanBenzMaxim | 21:00c94aeb533e | 141 | // 'page' - page number to swap in |
IanBenzMaxim | 21:00c94aeb533e | 142 | // 'region' - (1) first 1/2 page, (2) second 1/2 page, (3) entire page |
IanBenzMaxim | 21:00c94aeb533e | 143 | // |
IanBenzMaxim | 21:00c94aeb533e | 144 | // Returns: true write successful |
IanBenzMaxim | 21:00c94aeb533e | 145 | // false failure to complete read |
IanBenzMaxim | 21:00c94aeb533e | 146 | // |
IanBenzMaxim | 21:00c94aeb533e | 147 | OneWireMaster::CmdResult DS2465::Compute_SSecret(bool swap, unsigned int pageNum, PageRegion region) |
IanBenzMaxim | 21:00c94aeb533e | 148 | { |
IanBenzMaxim | 24:8942d8478d68 | 149 | uint8_t command[2] = { CMD_CSS, (swap ? (0xC8 | (pageNum << 4) | region) : 0xBF) }; |
IanBenzMaxim | 24:8942d8478d68 | 150 | return WriteMemory(ADDR_CMD_REG, command, 2); |
IanBenzMaxim | 21:00c94aeb533e | 151 | } |
IanBenzMaxim | 21:00c94aeb533e | 152 | |
IanBenzMaxim | 21:00c94aeb533e | 153 | |
IanBenzMaxim | 21:00c94aeb533e | 154 | |
IanBenzMaxim | 21:00c94aeb533e | 155 | |
IanBenzMaxim | 21:00c94aeb533e | 156 | ISha256MacCoprocessor::CmdResult DS2465::setMasterSecret(const std::uint8_t (&secret)[secret_len]) |
IanBenzMaxim | 21:00c94aeb533e | 157 | { |
IanBenzMaxim | 21:00c94aeb533e | 158 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 24:8942d8478d68 | 159 | result = WriteMemory(ADDR_SPAD, secret, secret_len); |
IanBenzMaxim | 21:00c94aeb533e | 160 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 161 | result = CopyScratchpad(1, 0, 1, 0); |
IanBenzMaxim | 21:00c94aeb533e | 162 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 163 | wait_ms(8 * EEPROM_WRITE_DELAY); |
IanBenzMaxim | 21:00c94aeb533e | 164 | return (result == OneWireMaster::Success ? ISha256MacCoprocessor::Success : ISha256MacCoprocessor::OperationFailure); |
IanBenzMaxim | 21:00c94aeb533e | 165 | } |
IanBenzMaxim | 21:00c94aeb533e | 166 | |
IanBenzMaxim | 21:00c94aeb533e | 167 | ISha256MacCoprocessor::CmdResult DS2465::ComputeAndRead_WriteMAC(const std::uint8_t (&WriteMAC_data)[WriteMAC_data_len], std::uint8_t (&mac)[mac_len]) const |
IanBenzMaxim | 21:00c94aeb533e | 168 | { |
IanBenzMaxim | 21:00c94aeb533e | 169 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 21:00c94aeb533e | 170 | // Write input data to scratchpad |
IanBenzMaxim | 24:8942d8478d68 | 171 | result = WriteScratchpad(WriteMAC_data, WriteMAC_data_len); |
IanBenzMaxim | 21:00c94aeb533e | 172 | // Compute MAC |
IanBenzMaxim | 21:00c94aeb533e | 173 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 174 | result = Compute_WriteMAC(false, false, 0, 0); |
IanBenzMaxim | 21:00c94aeb533e | 175 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 176 | { |
IanBenzMaxim | 21:00c94aeb533e | 177 | wait_ms(SHA_COMPUTATION_DELAY); |
IanBenzMaxim | 21:00c94aeb533e | 178 | // Read MAC from register |
IanBenzMaxim | 21:00c94aeb533e | 179 | result = ReadMemory(ADDR_MAC_READ, mac, mac_len, true); |
IanBenzMaxim | 21:00c94aeb533e | 180 | } |
IanBenzMaxim | 21:00c94aeb533e | 181 | return (result == OneWireMaster::Success ? ISha256MacCoprocessor::Success : ISha256MacCoprocessor::OperationFailure); |
IanBenzMaxim | 21:00c94aeb533e | 182 | } |
IanBenzMaxim | 21:00c94aeb533e | 183 | |
IanBenzMaxim | 21:00c94aeb533e | 184 | ISha256MacCoprocessor::CmdResult DS2465::ComputeAndRead_AuthMAC(const std::uint8_t (&devicePage)[devicePage_len], const std::uint8_t (&challenge)[deviceScratchpad_len], |
IanBenzMaxim | 21:00c94aeb533e | 185 | const std::uint8_t (&AuthMAC_data)[AuthMAC_data_len], std::uint8_t (&mac)[mac_len]) const |
IanBenzMaxim | 21:00c94aeb533e | 186 | { |
IanBenzMaxim | 21:00c94aeb533e | 187 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 21:00c94aeb533e | 188 | int addr = ADDR_SPAD; |
IanBenzMaxim | 21:00c94aeb533e | 189 | // Write input data to scratchpad |
IanBenzMaxim | 24:8942d8478d68 | 190 | result = CWriteMemory(addr, devicePage, devicePage_len); |
IanBenzMaxim | 21:00c94aeb533e | 191 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 192 | { |
IanBenzMaxim | 21:00c94aeb533e | 193 | addr += devicePage_len; |
IanBenzMaxim | 24:8942d8478d68 | 194 | result = CWriteMemory(addr, challenge, deviceScratchpad_len); |
IanBenzMaxim | 21:00c94aeb533e | 195 | } |
IanBenzMaxim | 21:00c94aeb533e | 196 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 197 | { |
IanBenzMaxim | 21:00c94aeb533e | 198 | addr += deviceScratchpad_len; |
IanBenzMaxim | 24:8942d8478d68 | 199 | result = CWriteMemory(addr, AuthMAC_data, AuthMAC_data_len); |
IanBenzMaxim | 21:00c94aeb533e | 200 | } |
IanBenzMaxim | 21:00c94aeb533e | 201 | // Compute MAC |
IanBenzMaxim | 21:00c94aeb533e | 202 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 203 | result = Compute_AuthMAC(false, 0, REGION_FULL_PAGE); |
IanBenzMaxim | 21:00c94aeb533e | 204 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 205 | { |
IanBenzMaxim | 21:00c94aeb533e | 206 | wait_ms(SHA_COMPUTATION_DELAY * 2); |
IanBenzMaxim | 21:00c94aeb533e | 207 | // Read MAC from register |
IanBenzMaxim | 21:00c94aeb533e | 208 | result = ReadMemory(ADDR_MAC_READ, mac, mac_len, true); |
IanBenzMaxim | 21:00c94aeb533e | 209 | } |
IanBenzMaxim | 21:00c94aeb533e | 210 | return (result == OneWireMaster::Success ? ISha256MacCoprocessor::Success : ISha256MacCoprocessor::OperationFailure); |
IanBenzMaxim | 21:00c94aeb533e | 211 | } |
IanBenzMaxim | 21:00c94aeb533e | 212 | |
IanBenzMaxim | 21:00c94aeb533e | 213 | ISha256MacCoprocessor::CmdResult DS2465::Compute_SSecret(const unsigned char (&devicePage)[devicePage_len], const unsigned char (&deviceScratchpad)[deviceScratchpad_len], |
IanBenzMaxim | 21:00c94aeb533e | 214 | const unsigned char (&SSecret_data)[SSecret_data_len]) |
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 | 24:8942d8478d68 | 219 | result = WriteMemory(addr, devicePage, devicePage_len); |
IanBenzMaxim | 21:00c94aeb533e | 220 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 221 | { |
IanBenzMaxim | 21:00c94aeb533e | 222 | addr += devicePage_len; |
IanBenzMaxim | 24:8942d8478d68 | 223 | result = WriteMemory(addr, deviceScratchpad, deviceScratchpad_len); |
IanBenzMaxim | 21:00c94aeb533e | 224 | } |
IanBenzMaxim | 21:00c94aeb533e | 225 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 226 | { |
IanBenzMaxim | 21:00c94aeb533e | 227 | addr += deviceScratchpad_len; |
IanBenzMaxim | 24:8942d8478d68 | 228 | result = WriteMemory(addr, SSecret_data, SSecret_data_len); |
IanBenzMaxim | 21:00c94aeb533e | 229 | } |
IanBenzMaxim | 21:00c94aeb533e | 230 | // Compute secret |
IanBenzMaxim | 21:00c94aeb533e | 231 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 232 | result = Compute_SSecret(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 | 24:8942d8478d68 | 251 | 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 | 21:00c94aeb533e | 255 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 256 | // APU enable or disable |
IanBenzMaxim | 21:00c94aeb533e | 257 | // |
IanBenzMaxim | 21:00c94aeb533e | 258 | // 'readflag' - 1 if reading current configuration |
IanBenzMaxim | 21:00c94aeb533e | 259 | // 'apu_enable' - 1 to enable |
IanBenzMaxim | 21:00c94aeb533e | 260 | // |
IanBenzMaxim | 21:00c94aeb533e | 261 | // Returns: true if write successful, or return configuration value if reading |
IanBenzMaxim | 21:00c94aeb533e | 262 | // |
IanBenzMaxim | 21:00c94aeb533e | 263 | OneWireMaster::CmdResult DS2465::ConfigureAPU(bool apu_enable) |
IanBenzMaxim | 21:00c94aeb533e | 264 | { |
IanBenzMaxim | 26:a361e3f42ba5 | 265 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 26:a361e3f42ba5 | 266 | if (m_curConfig.cAPU != apu_enable) |
IanBenzMaxim | 26:a361e3f42ba5 | 267 | { |
IanBenzMaxim | 26:a361e3f42ba5 | 268 | m_curConfig.cAPU = apu_enable; |
IanBenzMaxim | 26:a361e3f42ba5 | 269 | result = WriteConfig(m_curConfig); |
IanBenzMaxim | 26:a361e3f42ba5 | 270 | } |
IanBenzMaxim | 26:a361e3f42ba5 | 271 | else |
IanBenzMaxim | 26:a361e3f42ba5 | 272 | { |
IanBenzMaxim | 26:a361e3f42ba5 | 273 | result = OneWireMaster::Success; |
IanBenzMaxim | 26:a361e3f42ba5 | 274 | } |
IanBenzMaxim | 26:a361e3f42ba5 | 275 | return result; |
IanBenzMaxim | 26:a361e3f42ba5 | 276 | } |
IanBenzMaxim | 26:a361e3f42ba5 | 277 | |
IanBenzMaxim | 21:00c94aeb533e | 278 | |
IanBenzMaxim | 26:a361e3f42ba5 | 279 | |
IanBenzMaxim | 26:a361e3f42ba5 | 280 | OneWireMaster::CmdResult DS2465::ConfigureSPU(bool spu_enable) |
IanBenzMaxim | 26:a361e3f42ba5 | 281 | { |
IanBenzMaxim | 26:a361e3f42ba5 | 282 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 26:a361e3f42ba5 | 283 | if (m_curConfig.cSPU != spu_enable) |
IanBenzMaxim | 26:a361e3f42ba5 | 284 | { |
IanBenzMaxim | 26:a361e3f42ba5 | 285 | m_curConfig.cSPU = spu_enable; |
IanBenzMaxim | 26:a361e3f42ba5 | 286 | result = WriteConfig(m_curConfig); |
IanBenzMaxim | 26:a361e3f42ba5 | 287 | } |
IanBenzMaxim | 26:a361e3f42ba5 | 288 | else |
IanBenzMaxim | 26:a361e3f42ba5 | 289 | { |
IanBenzMaxim | 26:a361e3f42ba5 | 290 | result = OneWireMaster::Success; |
IanBenzMaxim | 26:a361e3f42ba5 | 291 | } |
IanBenzMaxim | 26:a361e3f42ba5 | 292 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 293 | } |
IanBenzMaxim | 21:00c94aeb533e | 294 | |
IanBenzMaxim | 21:00c94aeb533e | 295 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 296 | // Power up 1-Wire using extended function |
IanBenzMaxim | 21:00c94aeb533e | 297 | // |
IanBenzMaxim | 21:00c94aeb533e | 298 | // Returns: true successful |
IanBenzMaxim | 21:00c94aeb533e | 299 | // false failure during communication |
IanBenzMaxim | 21:00c94aeb533e | 300 | // |
IanBenzMaxim | 26:a361e3f42ba5 | 301 | OneWireMaster::CmdResult DS2465::ConfigurePowerDown(bool pdn_enable) |
IanBenzMaxim | 21:00c94aeb533e | 302 | { |
IanBenzMaxim | 21:00c94aeb533e | 303 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 26:a361e3f42ba5 | 304 | if (m_curConfig.cPDN != pdn_enable) |
IanBenzMaxim | 21:00c94aeb533e | 305 | { |
IanBenzMaxim | 26:a361e3f42ba5 | 306 | m_curConfig.cPDN = pdn_enable; |
IanBenzMaxim | 26:a361e3f42ba5 | 307 | result = WriteConfig(m_curConfig); |
IanBenzMaxim | 26:a361e3f42ba5 | 308 | if (!pdn_enable) |
IanBenzMaxim | 26:a361e3f42ba5 | 309 | wait_ms(2); // Delay 2ms to allow units to power up |
IanBenzMaxim | 21:00c94aeb533e | 310 | } |
IanBenzMaxim | 26:a361e3f42ba5 | 311 | else |
IanBenzMaxim | 26:a361e3f42ba5 | 312 | { |
IanBenzMaxim | 26:a361e3f42ba5 | 313 | result = OneWireMaster::Success; |
IanBenzMaxim | 26:a361e3f42ba5 | 314 | } |
IanBenzMaxim | 21:00c94aeb533e | 315 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 316 | } |
IanBenzMaxim | 21:00c94aeb533e | 317 | |
IanBenzMaxim | 21:00c94aeb533e | 318 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 319 | // Set the 1-Wire Net line level pull-up to normal. The DS2465 does only |
IanBenzMaxim | 21:00c94aeb533e | 320 | // allows enabling strong pull-up on a bit or byte event. Consequently this |
IanBenzMaxim | 21:00c94aeb533e | 321 | // function only allows the MODE_STANDARD argument. To enable strong pull-up |
IanBenzMaxim | 21:00c94aeb533e | 322 | // use OWWriteBytePower or OWReadBitPower. |
IanBenzMaxim | 21:00c94aeb533e | 323 | // |
IanBenzMaxim | 21:00c94aeb533e | 324 | // 'new_level' - new level defined as |
IanBenzMaxim | 21:00c94aeb533e | 325 | // MODE_STANDARD 0x00 |
IanBenzMaxim | 21:00c94aeb533e | 326 | // |
IanBenzMaxim | 21:00c94aeb533e | 327 | // Returns: current 1-Wire Net level |
IanBenzMaxim | 21:00c94aeb533e | 328 | // |
IanBenzMaxim | 21:00c94aeb533e | 329 | OneWireMaster::CmdResult DS2465::OWLevel(OW_LEVEL new_level) |
IanBenzMaxim | 21:00c94aeb533e | 330 | { |
IanBenzMaxim | 21:00c94aeb533e | 331 | // function only will turn back to non-strong pull-up |
IanBenzMaxim | 21:00c94aeb533e | 332 | if (new_level != LEVEL_NORMAL) |
IanBenzMaxim | 21:00c94aeb533e | 333 | return OneWireMaster::OperationFailure; |
IanBenzMaxim | 21:00c94aeb533e | 334 | |
IanBenzMaxim | 21:00c94aeb533e | 335 | // clear the strong pull-up bit in the global config state |
IanBenzMaxim | 24:8942d8478d68 | 336 | m_curConfig.cSPU = false; |
IanBenzMaxim | 21:00c94aeb533e | 337 | |
IanBenzMaxim | 21:00c94aeb533e | 338 | // write the new config |
IanBenzMaxim | 24:8942d8478d68 | 339 | return WriteConfig(m_curConfig); |
IanBenzMaxim | 21:00c94aeb533e | 340 | } |
IanBenzMaxim | 21:00c94aeb533e | 341 | |
IanBenzMaxim | 21:00c94aeb533e | 342 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 343 | // Set the 1-Wire Net communication speed. |
IanBenzMaxim | 21:00c94aeb533e | 344 | // |
IanBenzMaxim | 21:00c94aeb533e | 345 | // 'new_speed' - new speed defined as |
IanBenzMaxim | 21:00c94aeb533e | 346 | // MODE_STANDARD 0x00 |
IanBenzMaxim | 21:00c94aeb533e | 347 | // MODE_OVERDRIVE 0x01 |
IanBenzMaxim | 21:00c94aeb533e | 348 | // |
IanBenzMaxim | 21:00c94aeb533e | 349 | // Returns: current 1-Wire Net speed |
IanBenzMaxim | 21:00c94aeb533e | 350 | // |
IanBenzMaxim | 21:00c94aeb533e | 351 | OneWireMaster::CmdResult DS2465::OWSpeed(OW_SPEED new_speed) |
IanBenzMaxim | 21:00c94aeb533e | 352 | { |
IanBenzMaxim | 24:8942d8478d68 | 353 | // set the speed |
IanBenzMaxim | 24:8942d8478d68 | 354 | m_curConfig.c1WS = (new_speed == SPEED_OVERDRIVE); |
IanBenzMaxim | 21:00c94aeb533e | 355 | |
IanBenzMaxim | 21:00c94aeb533e | 356 | // write the new config |
IanBenzMaxim | 24:8942d8478d68 | 357 | return WriteConfig(m_curConfig); |
IanBenzMaxim | 21:00c94aeb533e | 358 | } |
IanBenzMaxim | 21:00c94aeb533e | 359 | |
IanBenzMaxim | 21:00c94aeb533e | 360 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 361 | // Use the DS2465 help command '1-Wire triplet' to perform one bit of a 1-Wire |
IanBenzMaxim | 21:00c94aeb533e | 362 | // search. This command does two read bits and one write bit. The write bit |
IanBenzMaxim | 21:00c94aeb533e | 363 | // is either the default direction (all device have same bit) or in case of |
IanBenzMaxim | 21:00c94aeb533e | 364 | // a discripancy, the 'search_direction' parameter is used. |
IanBenzMaxim | 21:00c94aeb533e | 365 | // |
j3 | 22:686273e55cdc | 366 | // Returns � The DS2465 status byte result from the triplet command |
IanBenzMaxim | 21:00c94aeb533e | 367 | // |
IanBenzMaxim | 21:00c94aeb533e | 368 | OneWireMaster::CmdResult DS2465::Triplet(Direction search_direction, uint8_t & status) |
IanBenzMaxim | 21:00c94aeb533e | 369 | { |
IanBenzMaxim | 21:00c94aeb533e | 370 | // 1-Wire Triplet (Case B) |
IanBenzMaxim | 21:00c94aeb533e | 371 | // S AD,0 [A] 1WT [A] SS [A] Sr AD,1 [A] [Status] A [Status] A\ P |
IanBenzMaxim | 21:00c94aeb533e | 372 | // \--------/ |
IanBenzMaxim | 21:00c94aeb533e | 373 | // Repeat until 1WB bit has changed to 0 |
IanBenzMaxim | 21:00c94aeb533e | 374 | // [] indicates from slave |
IanBenzMaxim | 21:00c94aeb533e | 375 | // SS indicates byte containing search direction bit value in msbit |
IanBenzMaxim | 24:8942d8478d68 | 376 | |
IanBenzMaxim | 24:8942d8478d68 | 377 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 24:8942d8478d68 | 378 | uint8_t command[2] = { CMD_1WT, ((search_direction == DIRECTION_WRITE_ONE) ? 0x80 : 0x00) }; |
IanBenzMaxim | 24:8942d8478d68 | 379 | result = WriteMemory(ADDR_CMD_REG, command, 2); |
IanBenzMaxim | 24:8942d8478d68 | 380 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 24:8942d8478d68 | 381 | result = PollBusy(&status); |
IanBenzMaxim | 24:8942d8478d68 | 382 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 383 | } |
IanBenzMaxim | 21:00c94aeb533e | 384 | |
IanBenzMaxim | 21:00c94aeb533e | 385 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 386 | // The 'OWSearch' function does a general search. This function |
IanBenzMaxim | 21:00c94aeb533e | 387 | // continues from the previos search state. The search state |
IanBenzMaxim | 21:00c94aeb533e | 388 | // can be reset by using the 'OWFirst' function. |
IanBenzMaxim | 21:00c94aeb533e | 389 | // This function contains one parameter 'alarm_only'. |
IanBenzMaxim | 21:00c94aeb533e | 390 | // When 'alarm_only' is true (1) the find alarm command |
IanBenzMaxim | 21:00c94aeb533e | 391 | // 0xEC is sent instead of the normal search command 0xF0. |
IanBenzMaxim | 21:00c94aeb533e | 392 | // Using the find alarm command 0xEC will limit the search to only |
IanBenzMaxim | 21:00c94aeb533e | 393 | // 1-Wire devices that are in an 'alarm' state. |
IanBenzMaxim | 21:00c94aeb533e | 394 | // |
IanBenzMaxim | 21:00c94aeb533e | 395 | // Returns: true (1) : when a 1-Wire device was found and it's |
IanBenzMaxim | 21:00c94aeb533e | 396 | // Serial Number placed in the global ROM |
IanBenzMaxim | 21:00c94aeb533e | 397 | // false (0): when no new device was found. Either the |
IanBenzMaxim | 21:00c94aeb533e | 398 | // last search was the last device or there |
IanBenzMaxim | 21:00c94aeb533e | 399 | // are no devices on the 1-Wire Net. |
IanBenzMaxim | 21:00c94aeb533e | 400 | // |
IanBenzMaxim | 21:00c94aeb533e | 401 | OneWireMaster::CmdResult DS2465::OWSearch(RomId & romId) |
IanBenzMaxim | 21:00c94aeb533e | 402 | { |
IanBenzMaxim | 21:00c94aeb533e | 403 | int id_bit_number; |
IanBenzMaxim | 21:00c94aeb533e | 404 | int last_zero, rom_byte_number; |
IanBenzMaxim | 21:00c94aeb533e | 405 | int id_bit, cmp_id_bit; |
IanBenzMaxim | 21:00c94aeb533e | 406 | unsigned char rom_byte_mask, status; |
IanBenzMaxim | 21:00c94aeb533e | 407 | bool search_result; |
IanBenzMaxim | 21:00c94aeb533e | 408 | unsigned char crc8 = 0; |
IanBenzMaxim | 21:00c94aeb533e | 409 | Direction search_direction; |
IanBenzMaxim | 21:00c94aeb533e | 410 | |
IanBenzMaxim | 21:00c94aeb533e | 411 | // initialize for search |
IanBenzMaxim | 21:00c94aeb533e | 412 | id_bit_number = 1; |
IanBenzMaxim | 21:00c94aeb533e | 413 | last_zero = 0; |
IanBenzMaxim | 21:00c94aeb533e | 414 | rom_byte_number = 0; |
IanBenzMaxim | 21:00c94aeb533e | 415 | rom_byte_mask = 1; |
IanBenzMaxim | 21:00c94aeb533e | 416 | search_result = false; |
IanBenzMaxim | 21:00c94aeb533e | 417 | |
IanBenzMaxim | 21:00c94aeb533e | 418 | // if the last call was not the last one |
IanBenzMaxim | 24:8942d8478d68 | 419 | if (!_last_device_flag) |
IanBenzMaxim | 21:00c94aeb533e | 420 | { |
IanBenzMaxim | 21:00c94aeb533e | 421 | // 1-Wire reset |
IanBenzMaxim | 21:00c94aeb533e | 422 | OneWireMaster::CmdResult result = OWReset(); |
IanBenzMaxim | 21:00c94aeb533e | 423 | if (result != OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 424 | { |
IanBenzMaxim | 21:00c94aeb533e | 425 | // reset the search |
IanBenzMaxim | 24:8942d8478d68 | 426 | _last_discrepancy = 0; |
IanBenzMaxim | 24:8942d8478d68 | 427 | _last_device_flag = false; |
IanBenzMaxim | 24:8942d8478d68 | 428 | _last_family_discrepancy = 0; |
IanBenzMaxim | 21:00c94aeb533e | 429 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 430 | } |
IanBenzMaxim | 21:00c94aeb533e | 431 | |
IanBenzMaxim | 21:00c94aeb533e | 432 | // issue the search command |
IanBenzMaxim | 26:a361e3f42ba5 | 433 | OneWireMaster::OWWriteByte(0xF0); |
IanBenzMaxim | 21:00c94aeb533e | 434 | |
IanBenzMaxim | 21:00c94aeb533e | 435 | // loop to do the search |
IanBenzMaxim | 21:00c94aeb533e | 436 | do |
IanBenzMaxim | 21:00c94aeb533e | 437 | { |
IanBenzMaxim | 21:00c94aeb533e | 438 | // if this discrepancy if before the Last Discrepancy |
IanBenzMaxim | 21:00c94aeb533e | 439 | // on a previous next then pick the same as last time |
IanBenzMaxim | 24:8942d8478d68 | 440 | if (id_bit_number < _last_discrepancy) |
IanBenzMaxim | 21:00c94aeb533e | 441 | { |
IanBenzMaxim | 21:00c94aeb533e | 442 | if ((romId[rom_byte_number] & rom_byte_mask) > 0) |
IanBenzMaxim | 21:00c94aeb533e | 443 | search_direction = DIRECTION_WRITE_ONE; |
IanBenzMaxim | 21:00c94aeb533e | 444 | else |
IanBenzMaxim | 21:00c94aeb533e | 445 | search_direction = DIRECTION_WRITE_ZERO; |
IanBenzMaxim | 21:00c94aeb533e | 446 | } |
IanBenzMaxim | 21:00c94aeb533e | 447 | else |
IanBenzMaxim | 21:00c94aeb533e | 448 | { |
IanBenzMaxim | 21:00c94aeb533e | 449 | // if equal to last pick 1, if not then pick 0 |
IanBenzMaxim | 24:8942d8478d68 | 450 | if (id_bit_number == _last_discrepancy) |
IanBenzMaxim | 21:00c94aeb533e | 451 | search_direction = DIRECTION_WRITE_ONE; |
IanBenzMaxim | 21:00c94aeb533e | 452 | else |
IanBenzMaxim | 21:00c94aeb533e | 453 | search_direction = DIRECTION_WRITE_ZERO; |
IanBenzMaxim | 21:00c94aeb533e | 454 | } |
IanBenzMaxim | 21:00c94aeb533e | 455 | |
IanBenzMaxim | 21:00c94aeb533e | 456 | // Peform a triple operation on the DS2465 which will perform 2 read bits and 1 write bit |
IanBenzMaxim | 21:00c94aeb533e | 457 | Triplet(search_direction, status); |
IanBenzMaxim | 21:00c94aeb533e | 458 | |
IanBenzMaxim | 21:00c94aeb533e | 459 | // check bit results in status byte |
IanBenzMaxim | 21:00c94aeb533e | 460 | id_bit = ((status & STATUS_SBR) == STATUS_SBR); |
IanBenzMaxim | 21:00c94aeb533e | 461 | cmp_id_bit = ((status & STATUS_TSB) == STATUS_TSB); |
IanBenzMaxim | 21:00c94aeb533e | 462 | search_direction = ((status & STATUS_DIR) == STATUS_DIR) ? DIRECTION_WRITE_ONE : DIRECTION_WRITE_ZERO; |
IanBenzMaxim | 21:00c94aeb533e | 463 | |
IanBenzMaxim | 21:00c94aeb533e | 464 | // check for no devices on 1-wire |
IanBenzMaxim | 21:00c94aeb533e | 465 | if ((id_bit) && (cmp_id_bit)) |
IanBenzMaxim | 21:00c94aeb533e | 466 | break; |
IanBenzMaxim | 21:00c94aeb533e | 467 | else |
IanBenzMaxim | 21:00c94aeb533e | 468 | { |
IanBenzMaxim | 21:00c94aeb533e | 469 | if ((!id_bit) && (!cmp_id_bit) && (search_direction == DIRECTION_WRITE_ZERO)) |
IanBenzMaxim | 21:00c94aeb533e | 470 | { |
IanBenzMaxim | 21:00c94aeb533e | 471 | last_zero = id_bit_number; |
IanBenzMaxim | 21:00c94aeb533e | 472 | |
IanBenzMaxim | 21:00c94aeb533e | 473 | // check for Last discrepancy in family |
IanBenzMaxim | 21:00c94aeb533e | 474 | if (last_zero < 9) |
IanBenzMaxim | 24:8942d8478d68 | 475 | _last_family_discrepancy = last_zero; |
IanBenzMaxim | 21:00c94aeb533e | 476 | } |
IanBenzMaxim | 21:00c94aeb533e | 477 | |
IanBenzMaxim | 21:00c94aeb533e | 478 | // set or clear the bit in the ROM byte rom_byte_number |
IanBenzMaxim | 21:00c94aeb533e | 479 | // with mask rom_byte_mask |
IanBenzMaxim | 21:00c94aeb533e | 480 | if (search_direction == DIRECTION_WRITE_ONE) |
IanBenzMaxim | 21:00c94aeb533e | 481 | romId[rom_byte_number] |= rom_byte_mask; |
IanBenzMaxim | 21:00c94aeb533e | 482 | else |
IanBenzMaxim | 21:00c94aeb533e | 483 | romId[rom_byte_number] &= (unsigned char)~rom_byte_mask; |
IanBenzMaxim | 21:00c94aeb533e | 484 | |
IanBenzMaxim | 21:00c94aeb533e | 485 | // increment the byte counter id_bit_number |
IanBenzMaxim | 21:00c94aeb533e | 486 | // and shift the mask rom_byte_mask |
IanBenzMaxim | 21:00c94aeb533e | 487 | id_bit_number++; |
IanBenzMaxim | 21:00c94aeb533e | 488 | rom_byte_mask <<= 1; |
IanBenzMaxim | 21:00c94aeb533e | 489 | |
IanBenzMaxim | 21:00c94aeb533e | 490 | // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask |
IanBenzMaxim | 21:00c94aeb533e | 491 | if (rom_byte_mask == 0) |
IanBenzMaxim | 21:00c94aeb533e | 492 | { |
IanBenzMaxim | 21:00c94aeb533e | 493 | crc8 = RomId::calculateCRC8(crc8, romId[rom_byte_number]); // accumulate the CRC |
IanBenzMaxim | 21:00c94aeb533e | 494 | rom_byte_number++; |
IanBenzMaxim | 21:00c94aeb533e | 495 | rom_byte_mask = 1; |
IanBenzMaxim | 21:00c94aeb533e | 496 | } |
IanBenzMaxim | 21:00c94aeb533e | 497 | } |
IanBenzMaxim | 21:00c94aeb533e | 498 | } |
IanBenzMaxim | 21:00c94aeb533e | 499 | while(rom_byte_number < RomId::byteLen); // loop until through all ROM bytes 0-7 |
IanBenzMaxim | 21:00c94aeb533e | 500 | |
IanBenzMaxim | 21:00c94aeb533e | 501 | // if the search was successful then |
IanBenzMaxim | 21:00c94aeb533e | 502 | if (!((id_bit_number <= (RomId::byteLen * 8)) || (crc8 != 0))) |
IanBenzMaxim | 21:00c94aeb533e | 503 | { |
IanBenzMaxim | 24:8942d8478d68 | 504 | // search successful so set m_last_discrepancy,m_last_device_flag,search_result |
IanBenzMaxim | 24:8942d8478d68 | 505 | _last_discrepancy = last_zero; |
IanBenzMaxim | 21:00c94aeb533e | 506 | |
IanBenzMaxim | 21:00c94aeb533e | 507 | // check for last device |
IanBenzMaxim | 24:8942d8478d68 | 508 | if (_last_discrepancy == 0) |
IanBenzMaxim | 24:8942d8478d68 | 509 | _last_device_flag = true; |
IanBenzMaxim | 21:00c94aeb533e | 510 | |
IanBenzMaxim | 21:00c94aeb533e | 511 | search_result = true; |
IanBenzMaxim | 21:00c94aeb533e | 512 | } |
IanBenzMaxim | 21:00c94aeb533e | 513 | } |
IanBenzMaxim | 21:00c94aeb533e | 514 | |
IanBenzMaxim | 21:00c94aeb533e | 515 | // if no device found then reset counters so next 'search' will be like a first |
IanBenzMaxim | 21:00c94aeb533e | 516 | if (!search_result || (romId.familyCode() == 0)) |
IanBenzMaxim | 21:00c94aeb533e | 517 | { |
IanBenzMaxim | 24:8942d8478d68 | 518 | _last_discrepancy = 0; |
IanBenzMaxim | 24:8942d8478d68 | 519 | _last_device_flag = false; |
IanBenzMaxim | 24:8942d8478d68 | 520 | _last_family_discrepancy = 0; |
IanBenzMaxim | 21:00c94aeb533e | 521 | search_result = false; |
IanBenzMaxim | 21:00c94aeb533e | 522 | } |
IanBenzMaxim | 21:00c94aeb533e | 523 | |
IanBenzMaxim | 21:00c94aeb533e | 524 | return search_result ? OneWireMaster::Success : OneWireMaster::OperationFailure; |
IanBenzMaxim | 21:00c94aeb533e | 525 | } |
IanBenzMaxim | 21:00c94aeb533e | 526 | |
IanBenzMaxim | 21:00c94aeb533e | 527 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 528 | // The 'OWReadBlock' receives a block of data from the |
IanBenzMaxim | 21:00c94aeb533e | 529 | // 1-Wire Net. The destination is the mac buffer (rx_mac=1) or |
IanBenzMaxim | 21:00c94aeb533e | 530 | // the scratchpad (rx_mac=0). The result is buffer is returned. |
IanBenzMaxim | 21:00c94aeb533e | 531 | // |
IanBenzMaxim | 21:00c94aeb533e | 532 | // 'rx_buf' - pointer to a block to receive bytes |
IanBenzMaxim | 21:00c94aeb533e | 533 | // of length 'rx_len' from 1-Wire Net |
IanBenzMaxim | 21:00c94aeb533e | 534 | // 'rx_len' - length in bytes to read. Only valid numbers are 8,16,20,32; |
IanBenzMaxim | 21:00c94aeb533e | 535 | // |
IanBenzMaxim | 21:00c94aeb533e | 536 | OneWireMaster::CmdResult DS2465::OWReadBlock(uint8_t *rx_buf, uint8_t rx_len) |
IanBenzMaxim | 21:00c94aeb533e | 537 | { |
IanBenzMaxim | 21:00c94aeb533e | 538 | // 1-Wire Receive Block (Case A) |
IanBenzMaxim | 21:00c94aeb533e | 539 | // S AD,0 [A] ADDR_CMD_REG [A] 1WRF [A] PR [A] P |
IanBenzMaxim | 21:00c94aeb533e | 540 | // [] indicates from slave |
IanBenzMaxim | 21:00c94aeb533e | 541 | // PR indicates byte containing parameter |
IanBenzMaxim | 21:00c94aeb533e | 542 | |
IanBenzMaxim | 24:8942d8478d68 | 543 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 24:8942d8478d68 | 544 | uint8_t command[2] = { CMD_1WRF, rx_len }; |
IanBenzMaxim | 24:8942d8478d68 | 545 | |
IanBenzMaxim | 24:8942d8478d68 | 546 | result = WriteMemory(ADDR_CMD_REG, command, 2); |
IanBenzMaxim | 24:8942d8478d68 | 547 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 24:8942d8478d68 | 548 | result = PollBusy(); |
IanBenzMaxim | 24:8942d8478d68 | 549 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 24:8942d8478d68 | 550 | result = ReadMemory(ADDR_SPAD, rx_buf, rx_len, false); |
IanBenzMaxim | 21:00c94aeb533e | 551 | |
IanBenzMaxim | 24:8942d8478d68 | 552 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 553 | } |
IanBenzMaxim | 21:00c94aeb533e | 554 | |
IanBenzMaxim | 21:00c94aeb533e | 555 | |
IanBenzMaxim | 21:00c94aeb533e | 556 | |
IanBenzMaxim | 21:00c94aeb533e | 557 | |
IanBenzMaxim | 21:00c94aeb533e | 558 | OneWireMaster::CmdResult DS2465::OWWriteBlock(const uint8_t *tran_buf, uint8_t tran_len) |
IanBenzMaxim | 21:00c94aeb533e | 559 | { |
IanBenzMaxim | 21:00c94aeb533e | 560 | return OWWriteBlock(false, tran_buf, tran_len); |
IanBenzMaxim | 21:00c94aeb533e | 561 | } |
IanBenzMaxim | 21:00c94aeb533e | 562 | |
IanBenzMaxim | 21:00c94aeb533e | 563 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 564 | // The 'OWWriteBlock' transfers a block of data to the |
IanBenzMaxim | 21:00c94aeb533e | 565 | // 1-Wire Net. The mac buffer can be sent (tx_mac=1) or a |
IanBenzMaxim | 21:00c94aeb533e | 566 | // portion of the scratchpad can be sent. |
IanBenzMaxim | 21:00c94aeb533e | 567 | // |
IanBenzMaxim | 21:00c94aeb533e | 568 | // 'tx_mac' - flag to indicate if the MAC buffer is to be sent (1) or |
IanBenzMaxim | 21:00c94aeb533e | 569 | // the data provided in teh tran_buf is to be sent (0) |
IanBenzMaxim | 21:00c94aeb533e | 570 | // 'tran_buf' - pointer to a block of bytes |
IanBenzMaxim | 21:00c94aeb533e | 571 | // of length 'tran_len' that will be sent |
IanBenzMaxim | 21:00c94aeb533e | 572 | // to the 1-Wire Net |
IanBenzMaxim | 21:00c94aeb533e | 573 | // 'tran_len' - length in bytes to transfer. Only valid numbers are 8,16,20,32; |
IanBenzMaxim | 21:00c94aeb533e | 574 | // |
IanBenzMaxim | 21:00c94aeb533e | 575 | OneWireMaster::CmdResult DS2465::OWWriteBlock(bool tx_mac, const uint8_t *tran_buf, uint8_t tran_len) |
IanBenzMaxim | 21:00c94aeb533e | 576 | { |
IanBenzMaxim | 21:00c94aeb533e | 577 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 24:8942d8478d68 | 578 | uint8_t command[2] = { CMD_1WTB, (tx_mac ? 0xFF : tran_len) }; |
IanBenzMaxim | 21:00c94aeb533e | 579 | |
IanBenzMaxim | 24:8942d8478d68 | 580 | if (!tx_mac) |
IanBenzMaxim | 21:00c94aeb533e | 581 | { |
IanBenzMaxim | 21:00c94aeb533e | 582 | // prefill scratchpad with required data |
IanBenzMaxim | 24:8942d8478d68 | 583 | result = WriteMemory(ADDR_SPAD, tran_buf, tran_len); |
IanBenzMaxim | 21:00c94aeb533e | 584 | if (result != OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 585 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 586 | } |
IanBenzMaxim | 21:00c94aeb533e | 587 | |
IanBenzMaxim | 21:00c94aeb533e | 588 | // 1-Wire Transmit Block (Case A) |
IanBenzMaxim | 21:00c94aeb533e | 589 | // S AD,0 [A] ADDR_CMD_REG [A] 1WTB [A] PR [A] P |
IanBenzMaxim | 21:00c94aeb533e | 590 | // [] indicates from slave |
IanBenzMaxim | 21:00c94aeb533e | 591 | // PR indicates byte containing parameter |
IanBenzMaxim | 24:8942d8478d68 | 592 | |
IanBenzMaxim | 24:8942d8478d68 | 593 | result = WriteMemory(ADDR_CMD_REG, command, 2); |
IanBenzMaxim | 24:8942d8478d68 | 594 | |
IanBenzMaxim | 24:8942d8478d68 | 595 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 24:8942d8478d68 | 596 | result = PollBusy(); |
IanBenzMaxim | 21:00c94aeb533e | 597 | |
IanBenzMaxim | 24:8942d8478d68 | 598 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 599 | } |
IanBenzMaxim | 21:00c94aeb533e | 600 | |
IanBenzMaxim | 21:00c94aeb533e | 601 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 602 | // Send 8 bits of read communication to the 1-Wire Net and return the |
IanBenzMaxim | 21:00c94aeb533e | 603 | // result 8 bits read from the 1-Wire Net. |
IanBenzMaxim | 21:00c94aeb533e | 604 | // |
IanBenzMaxim | 21:00c94aeb533e | 605 | // Returns: 8 bits read from 1-Wire Net |
IanBenzMaxim | 21:00c94aeb533e | 606 | // |
IanBenzMaxim | 26:a361e3f42ba5 | 607 | OneWireMaster::CmdResult DS2465::OWReadByte(uint8_t & recvbyte, OW_LEVEL after_level) |
IanBenzMaxim | 21:00c94aeb533e | 608 | { |
IanBenzMaxim | 24:8942d8478d68 | 609 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 24:8942d8478d68 | 610 | uint8_t buf; |
IanBenzMaxim | 21:00c94aeb533e | 611 | |
IanBenzMaxim | 24:8942d8478d68 | 612 | // 1-Wire Read Bytes (Case C) |
IanBenzMaxim | 24:8942d8478d68 | 613 | // S AD,0 [A] ADDR_CMD_REG [A] 1WRB [A] Sr AD,1 [A] [Status] A [Status] A |
IanBenzMaxim | 24:8942d8478d68 | 614 | // \--------/ |
IanBenzMaxim | 24:8942d8478d68 | 615 | // Repeat until 1WB bit has changed to 0 |
IanBenzMaxim | 24:8942d8478d68 | 616 | // Sr AD,0 [A] SRP [A] E1 [A] Sr AD,1 [A] DD A\ P |
IanBenzMaxim | 24:8942d8478d68 | 617 | // |
IanBenzMaxim | 24:8942d8478d68 | 618 | // [] indicates from slave |
IanBenzMaxim | 24:8942d8478d68 | 619 | // DD data read |
IanBenzMaxim | 26:a361e3f42ba5 | 620 | |
IanBenzMaxim | 26:a361e3f42ba5 | 621 | result = ConfigureSPU(after_level == LEVEL_STRONG); |
IanBenzMaxim | 26:a361e3f42ba5 | 622 | if (result != OneWireMaster::Success) |
IanBenzMaxim | 26:a361e3f42ba5 | 623 | return result; |
IanBenzMaxim | 24:8942d8478d68 | 624 | |
IanBenzMaxim | 24:8942d8478d68 | 625 | buf = CMD_1WRB; |
IanBenzMaxim | 24:8942d8478d68 | 626 | result = WriteMemory(ADDR_CMD_REG, &buf, 1); |
IanBenzMaxim | 21:00c94aeb533e | 627 | |
IanBenzMaxim | 24:8942d8478d68 | 628 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 24:8942d8478d68 | 629 | result = PollBusy(); |
IanBenzMaxim | 24:8942d8478d68 | 630 | |
IanBenzMaxim | 24:8942d8478d68 | 631 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 24:8942d8478d68 | 632 | result = ReadMemory(ADDR_DATA_REG, &buf, 1); |
IanBenzMaxim | 21:00c94aeb533e | 633 | |
IanBenzMaxim | 24:8942d8478d68 | 634 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 24:8942d8478d68 | 635 | recvbyte = buf; |
IanBenzMaxim | 21:00c94aeb533e | 636 | |
IanBenzMaxim | 24:8942d8478d68 | 637 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 638 | } |
IanBenzMaxim | 21:00c94aeb533e | 639 | |
IanBenzMaxim | 21:00c94aeb533e | 640 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 641 | // Send 8 bits of communication to the 1-Wire Net and verify that the |
IanBenzMaxim | 21:00c94aeb533e | 642 | // 8 bits read from the 1-Wire Net is the same (write operation). |
IanBenzMaxim | 21:00c94aeb533e | 643 | // The parameter 'sendbyte' least significant 8 bits are used. |
IanBenzMaxim | 21:00c94aeb533e | 644 | // |
IanBenzMaxim | 21:00c94aeb533e | 645 | // 'sendbyte' - 8 bits to send (least significant byte) |
IanBenzMaxim | 21:00c94aeb533e | 646 | // |
IanBenzMaxim | 21:00c94aeb533e | 647 | // Returns: true: bytes written and echo was the same |
IanBenzMaxim | 21:00c94aeb533e | 648 | // false: echo was not the same |
IanBenzMaxim | 21:00c94aeb533e | 649 | // |
IanBenzMaxim | 26:a361e3f42ba5 | 650 | OneWireMaster::CmdResult DS2465::OWWriteByte(uint8_t sendbyte, OW_LEVEL after_level) |
IanBenzMaxim | 24:8942d8478d68 | 651 | { |
IanBenzMaxim | 21:00c94aeb533e | 652 | // 1-Wire Write Byte (Case B) |
IanBenzMaxim | 21:00c94aeb533e | 653 | // S AD,0 [A] ADDR_CMD_REG [A] 1WWB [A] DD [A] Sr AD,1 [A] [Status] A [Status] A\ P |
IanBenzMaxim | 21:00c94aeb533e | 654 | // \--------/ |
IanBenzMaxim | 21:00c94aeb533e | 655 | // Repeat until 1WB bit has changed to 0 |
IanBenzMaxim | 21:00c94aeb533e | 656 | // [] indicates from slave |
IanBenzMaxim | 21:00c94aeb533e | 657 | // DD data to write |
IanBenzMaxim | 24:8942d8478d68 | 658 | |
IanBenzMaxim | 24:8942d8478d68 | 659 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 26:a361e3f42ba5 | 660 | |
IanBenzMaxim | 26:a361e3f42ba5 | 661 | result = ConfigureSPU(after_level == LEVEL_STRONG); |
IanBenzMaxim | 26:a361e3f42ba5 | 662 | if (result != OneWireMaster::Success) |
IanBenzMaxim | 26:a361e3f42ba5 | 663 | return result; |
IanBenzMaxim | 26:a361e3f42ba5 | 664 | |
IanBenzMaxim | 24:8942d8478d68 | 665 | uint8_t command[2] = { CMD_1WWB, sendbyte }; |
IanBenzMaxim | 24:8942d8478d68 | 666 | |
IanBenzMaxim | 24:8942d8478d68 | 667 | result = WriteMemory(ADDR_CMD_REG, command, 2); |
IanBenzMaxim | 24:8942d8478d68 | 668 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 24:8942d8478d68 | 669 | result = PollBusy(); |
IanBenzMaxim | 21:00c94aeb533e | 670 | |
IanBenzMaxim | 24:8942d8478d68 | 671 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 672 | } |
IanBenzMaxim | 21:00c94aeb533e | 673 | |
IanBenzMaxim | 21:00c94aeb533e | 674 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 675 | // Send 1 bit of communication to the 1-Wire Net and return the |
IanBenzMaxim | 21:00c94aeb533e | 676 | // result 1 bit read from the 1-Wire Net. The parameter 'sendbit' |
IanBenzMaxim | 21:00c94aeb533e | 677 | // least significant bit is used and the least significant bit |
IanBenzMaxim | 21:00c94aeb533e | 678 | // of the result is the return bit. |
IanBenzMaxim | 21:00c94aeb533e | 679 | // |
IanBenzMaxim | 21:00c94aeb533e | 680 | // 'sendbit' - the least significant bit is the bit to send |
IanBenzMaxim | 21:00c94aeb533e | 681 | // |
IanBenzMaxim | 21:00c94aeb533e | 682 | // Returns: 0: 0 bit read from sendbit |
IanBenzMaxim | 21:00c94aeb533e | 683 | // 1: 1 bit read from sendbit |
IanBenzMaxim | 21:00c94aeb533e | 684 | // |
IanBenzMaxim | 26:a361e3f42ba5 | 685 | OneWireMaster::CmdResult DS2465::OWTouchBit(uint8_t & sendrecvbit, OW_LEVEL after_level) |
IanBenzMaxim | 21:00c94aeb533e | 686 | { |
IanBenzMaxim | 21:00c94aeb533e | 687 | // 1-Wire bit (Case B) |
IanBenzMaxim | 21:00c94aeb533e | 688 | // S AD,0 [A] ADDR_CMD_REG [A] 1WSB [A] BB [A] Sr AD,1 [A] [Status] A [Status] A\ P |
IanBenzMaxim | 21:00c94aeb533e | 689 | // \--------/ |
IanBenzMaxim | 21:00c94aeb533e | 690 | // Repeat until 1WB bit has changed to 0 |
IanBenzMaxim | 21:00c94aeb533e | 691 | // [] indicates from slave |
IanBenzMaxim | 21:00c94aeb533e | 692 | // BB indicates byte containing bit value in msbit |
IanBenzMaxim | 21:00c94aeb533e | 693 | |
IanBenzMaxim | 24:8942d8478d68 | 694 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 26:a361e3f42ba5 | 695 | |
IanBenzMaxim | 26:a361e3f42ba5 | 696 | result = ConfigureSPU(after_level == LEVEL_STRONG); |
IanBenzMaxim | 26:a361e3f42ba5 | 697 | if (result != OneWireMaster::Success) |
IanBenzMaxim | 26:a361e3f42ba5 | 698 | return result; |
IanBenzMaxim | 26:a361e3f42ba5 | 699 | |
IanBenzMaxim | 24:8942d8478d68 | 700 | uint8_t command[2] = { CMD_1WSB, (sendrecvbit ? 0x80 : 0x00) }; |
IanBenzMaxim | 24:8942d8478d68 | 701 | uint8_t status; |
IanBenzMaxim | 24:8942d8478d68 | 702 | |
IanBenzMaxim | 24:8942d8478d68 | 703 | result = WriteMemory(ADDR_CMD_REG, command, 2); |
IanBenzMaxim | 21:00c94aeb533e | 704 | |
IanBenzMaxim | 24:8942d8478d68 | 705 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 24:8942d8478d68 | 706 | result = PollBusy(&status); |
IanBenzMaxim | 21:00c94aeb533e | 707 | |
IanBenzMaxim | 24:8942d8478d68 | 708 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 24:8942d8478d68 | 709 | sendrecvbit = (status & STATUS_SBR); |
IanBenzMaxim | 24:8942d8478d68 | 710 | |
IanBenzMaxim | 24:8942d8478d68 | 711 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 712 | } |
IanBenzMaxim | 21:00c94aeb533e | 713 | |
IanBenzMaxim | 21:00c94aeb533e | 714 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 715 | // Write to Scratchpad (SRAM) memory on the DS2465 |
IanBenzMaxim | 21:00c94aeb533e | 716 | // |
IanBenzMaxim | 21:00c94aeb533e | 717 | // 'addr' - address to start writing (must be in SRAM) |
IanBenzMaxim | 21:00c94aeb533e | 718 | // 'buf' - buffer of data to write |
IanBenzMaxim | 21:00c94aeb533e | 719 | // 'len' - length to write |
IanBenzMaxim | 21:00c94aeb533e | 720 | // |
IanBenzMaxim | 21:00c94aeb533e | 721 | // Returns: true write successful |
IanBenzMaxim | 21:00c94aeb533e | 722 | // false failure to complete write |
IanBenzMaxim | 21:00c94aeb533e | 723 | // |
IanBenzMaxim | 24:8942d8478d68 | 724 | OneWireMaster::CmdResult DS2465::CWriteMemory(std::uint8_t addr, const std::uint8_t * buf, size_t bufLen) const |
IanBenzMaxim | 21:00c94aeb533e | 725 | { |
IanBenzMaxim | 21:00c94aeb533e | 726 | int i; |
IanBenzMaxim | 21:00c94aeb533e | 727 | |
IanBenzMaxim | 21:00c94aeb533e | 728 | // Write SRAM (Case A) |
IanBenzMaxim | 21:00c94aeb533e | 729 | // S AD,0 [A] VSA [A] DD [A] P |
IanBenzMaxim | 21:00c94aeb533e | 730 | // \-----/ |
IanBenzMaxim | 21:00c94aeb533e | 731 | // Repeat for each data byte |
IanBenzMaxim | 21:00c94aeb533e | 732 | // [] indicates from slave |
IanBenzMaxim | 21:00c94aeb533e | 733 | // VSA valid SRAM memory address |
IanBenzMaxim | 21:00c94aeb533e | 734 | // DD memory data to write |
IanBenzMaxim | 21:00c94aeb533e | 735 | |
IanBenzMaxim | 21:00c94aeb533e | 736 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 737 | if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 738 | { |
IanBenzMaxim | 21:00c94aeb533e | 739 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 740 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 741 | } |
IanBenzMaxim | 21:00c94aeb533e | 742 | if (m_I2C_interface.write((unsigned char)addr) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 743 | { |
IanBenzMaxim | 21:00c94aeb533e | 744 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 745 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 746 | } |
IanBenzMaxim | 21:00c94aeb533e | 747 | // loop to write each byte |
IanBenzMaxim | 21:00c94aeb533e | 748 | for (i = 0; i < bufLen; i++) |
IanBenzMaxim | 21:00c94aeb533e | 749 | { |
IanBenzMaxim | 21:00c94aeb533e | 750 | if (m_I2C_interface.write(buf[i]) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 751 | { |
IanBenzMaxim | 21:00c94aeb533e | 752 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 753 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 754 | } |
IanBenzMaxim | 21:00c94aeb533e | 755 | } |
IanBenzMaxim | 21:00c94aeb533e | 756 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 757 | |
IanBenzMaxim | 21:00c94aeb533e | 758 | return OneWireMaster::Success; |
IanBenzMaxim | 21:00c94aeb533e | 759 | } |
IanBenzMaxim | 21:00c94aeb533e | 760 | |
IanBenzMaxim | 21:00c94aeb533e | 761 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 762 | // Read memory from the DS2465 |
IanBenzMaxim | 21:00c94aeb533e | 763 | // |
IanBenzMaxim | 21:00c94aeb533e | 764 | // 'addr' - address to start reading |
IanBenzMaxim | 21:00c94aeb533e | 765 | // 'buf' - buffer to hold memory read |
IanBenzMaxim | 21:00c94aeb533e | 766 | // 'len' - length to read |
IanBenzMaxim | 21:00c94aeb533e | 767 | // 'skip_set_pointer' - flag to indicate to skip setting address pointer |
IanBenzMaxim | 21:00c94aeb533e | 768 | // |
IanBenzMaxim | 21:00c94aeb533e | 769 | // Returns: true read successful |
IanBenzMaxim | 21:00c94aeb533e | 770 | // false failure to complete read |
IanBenzMaxim | 21:00c94aeb533e | 771 | // |
IanBenzMaxim | 21:00c94aeb533e | 772 | OneWireMaster::CmdResult DS2465::ReadMemory(std::uint8_t addr, std::uint8_t * buf, size_t bufLen, bool skip_set_pointer) const |
IanBenzMaxim | 21:00c94aeb533e | 773 | { |
IanBenzMaxim | 21:00c94aeb533e | 774 | int i; |
IanBenzMaxim | 21:00c94aeb533e | 775 | |
IanBenzMaxim | 21:00c94aeb533e | 776 | // Read (Case A) |
IanBenzMaxim | 21:00c94aeb533e | 777 | // S AD,0 [A] MA [A] Sr AD,1 [A] [DD] A [DD] A\ P |
IanBenzMaxim | 21:00c94aeb533e | 778 | // \-----/ |
IanBenzMaxim | 21:00c94aeb533e | 779 | // Repeat for each data byte, NAK last byte |
IanBenzMaxim | 21:00c94aeb533e | 780 | // [] indicates from slave |
IanBenzMaxim | 21:00c94aeb533e | 781 | // MA memory address |
IanBenzMaxim | 21:00c94aeb533e | 782 | // DD memory data read |
IanBenzMaxim | 21:00c94aeb533e | 783 | |
IanBenzMaxim | 21:00c94aeb533e | 784 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 785 | if (!skip_set_pointer) |
IanBenzMaxim | 21:00c94aeb533e | 786 | { |
IanBenzMaxim | 21:00c94aeb533e | 787 | if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 788 | { |
IanBenzMaxim | 21:00c94aeb533e | 789 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 790 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 791 | } |
IanBenzMaxim | 21:00c94aeb533e | 792 | if (m_I2C_interface.write((unsigned char)addr) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 793 | { |
IanBenzMaxim | 21:00c94aeb533e | 794 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 795 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 796 | } |
IanBenzMaxim | 21:00c94aeb533e | 797 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 798 | } |
IanBenzMaxim | 21:00c94aeb533e | 799 | |
IanBenzMaxim | 21:00c94aeb533e | 800 | if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_READ)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 801 | { |
IanBenzMaxim | 21:00c94aeb533e | 802 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 803 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 804 | } |
IanBenzMaxim | 21:00c94aeb533e | 805 | // loop to read each byte, NAK last byte |
IanBenzMaxim | 21:00c94aeb533e | 806 | for (i = 0; i < bufLen; i++) |
IanBenzMaxim | 21:00c94aeb533e | 807 | { |
IanBenzMaxim | 21:00c94aeb533e | 808 | buf[i] = m_I2C_interface.read((i == (bufLen - 1)) ? m_I2C_interface.NoACK : m_I2C_interface.ACK); |
IanBenzMaxim | 21:00c94aeb533e | 809 | } |
IanBenzMaxim | 21:00c94aeb533e | 810 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 811 | |
IanBenzMaxim | 21:00c94aeb533e | 812 | return OneWireMaster::Success; |
IanBenzMaxim | 21:00c94aeb533e | 813 | } |
IanBenzMaxim | 21:00c94aeb533e | 814 | |
IanBenzMaxim | 21:00c94aeb533e | 815 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 816 | // Write the configuration register in the DS2465. The configuration |
IanBenzMaxim | 21:00c94aeb533e | 817 | // options are provided in the lower nibble of the provided config byte. |
IanBenzMaxim | 21:00c94aeb533e | 818 | // The uppper nibble in bitwise inverted when written to the DS2465. |
IanBenzMaxim | 21:00c94aeb533e | 819 | // |
IanBenzMaxim | 21:00c94aeb533e | 820 | // Returns: true: config written and response correct |
IanBenzMaxim | 21:00c94aeb533e | 821 | // false: response incorrect |
IanBenzMaxim | 21:00c94aeb533e | 822 | // |
IanBenzMaxim | 24:8942d8478d68 | 823 | OneWireMaster::CmdResult DS2465::WriteConfig(const Config & config) |
IanBenzMaxim | 21:00c94aeb533e | 824 | { |
IanBenzMaxim | 24:8942d8478d68 | 825 | std::uint8_t configBuf; |
IanBenzMaxim | 24:8942d8478d68 | 826 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 21:00c94aeb533e | 827 | |
IanBenzMaxim | 24:8942d8478d68 | 828 | configBuf = config.writeByte(); |
IanBenzMaxim | 24:8942d8478d68 | 829 | result = WriteMemory(ADDR_WCFG_REG, &configBuf, 1); |
IanBenzMaxim | 24:8942d8478d68 | 830 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 831 | { |
IanBenzMaxim | 24:8942d8478d68 | 832 | result = ReadMemory(ADDR_WCFG_REG, &configBuf, 1); |
IanBenzMaxim | 24:8942d8478d68 | 833 | } |
IanBenzMaxim | 24:8942d8478d68 | 834 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 24:8942d8478d68 | 835 | { |
IanBenzMaxim | 24:8942d8478d68 | 836 | if (configBuf != config.readByte()) |
IanBenzMaxim | 24:8942d8478d68 | 837 | result = OneWireMaster::OperationFailure; |
IanBenzMaxim | 21:00c94aeb533e | 838 | } |
IanBenzMaxim | 21:00c94aeb533e | 839 | |
IanBenzMaxim | 24:8942d8478d68 | 840 | return result; |
IanBenzMaxim | 24:8942d8478d68 | 841 | } |
IanBenzMaxim | 24:8942d8478d68 | 842 | |
IanBenzMaxim | 24:8942d8478d68 | 843 | |
IanBenzMaxim | 24:8942d8478d68 | 844 | |
IanBenzMaxim | 24:8942d8478d68 | 845 | |
IanBenzMaxim | 24:8942d8478d68 | 846 | OneWireMaster::CmdResult DS2465::PollBusy(uint8_t * pStatus) |
IanBenzMaxim | 24:8942d8478d68 | 847 | { |
IanBenzMaxim | 24:8942d8478d68 | 848 | const unsigned int pollLimit = 200; |
IanBenzMaxim | 24:8942d8478d68 | 849 | |
IanBenzMaxim | 24:8942d8478d68 | 850 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 24:8942d8478d68 | 851 | uint8_t status; |
IanBenzMaxim | 24:8942d8478d68 | 852 | unsigned int pollCount = 0; |
IanBenzMaxim | 24:8942d8478d68 | 853 | |
IanBenzMaxim | 24:8942d8478d68 | 854 | // loop checking 1WB bit for completion of 1-Wire operation |
IanBenzMaxim | 24:8942d8478d68 | 855 | // abort if poll limit reached |
IanBenzMaxim | 24:8942d8478d68 | 856 | |
IanBenzMaxim | 24:8942d8478d68 | 857 | do |
IanBenzMaxim | 24:8942d8478d68 | 858 | { |
IanBenzMaxim | 24:8942d8478d68 | 859 | result = ReadMemory(ADDR_STATUS_REG, &status, 1, true); |
IanBenzMaxim | 24:8942d8478d68 | 860 | if (result != OneWireMaster::Success) |
IanBenzMaxim | 24:8942d8478d68 | 861 | return result; |
IanBenzMaxim | 24:8942d8478d68 | 862 | if (pStatus != NULL) |
IanBenzMaxim | 24:8942d8478d68 | 863 | *pStatus = status; |
IanBenzMaxim | 24:8942d8478d68 | 864 | if (pollCount++ >= pollLimit) |
IanBenzMaxim | 24:8942d8478d68 | 865 | return OneWireMaster::TimeoutError; |
IanBenzMaxim | 24:8942d8478d68 | 866 | } while (status & STATUS_1WB); |
IanBenzMaxim | 24:8942d8478d68 | 867 | |
IanBenzMaxim | 21:00c94aeb533e | 868 | return OneWireMaster::Success; |
IanBenzMaxim | 21:00c94aeb533e | 869 | } |
IanBenzMaxim | 21:00c94aeb533e | 870 | |
IanBenzMaxim | 21:00c94aeb533e | 871 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 872 | // Reset all of the devices on the 1-Wire Net and return the result. |
IanBenzMaxim | 21:00c94aeb533e | 873 | // |
IanBenzMaxim | 21:00c94aeb533e | 874 | // Returns: true(1): presense pulse(s) detected, device(s) reset |
IanBenzMaxim | 21:00c94aeb533e | 875 | // false(0): no presense pulses detected |
IanBenzMaxim | 21:00c94aeb533e | 876 | // |
IanBenzMaxim | 21:00c94aeb533e | 877 | OneWireMaster::CmdResult DS2465::OWReset(void) |
IanBenzMaxim | 24:8942d8478d68 | 878 | { |
IanBenzMaxim | 24:8942d8478d68 | 879 | // 1-Wire reset (Case B) |
IanBenzMaxim | 24:8942d8478d68 | 880 | // S AD,0 [A] ADDR_CMD_REG [A] 1WRS [A] Sr AD,1 [A] [Status] A [Status] A\ P |
IanBenzMaxim | 24:8942d8478d68 | 881 | // \--------/ |
IanBenzMaxim | 24:8942d8478d68 | 882 | // Repeat until 1WB bit has changed to 0 |
IanBenzMaxim | 24:8942d8478d68 | 883 | // [] indicates from slave |
IanBenzMaxim | 21:00c94aeb533e | 884 | |
IanBenzMaxim | 24:8942d8478d68 | 885 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 24:8942d8478d68 | 886 | uint8_t buf; |
IanBenzMaxim | 21:00c94aeb533e | 887 | |
IanBenzMaxim | 24:8942d8478d68 | 888 | buf = CMD_1WRS; |
IanBenzMaxim | 24:8942d8478d68 | 889 | result = WriteMemory(ADDR_CMD_REG, &buf, 1); |
IanBenzMaxim | 21:00c94aeb533e | 890 | |
IanBenzMaxim | 24:8942d8478d68 | 891 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 24:8942d8478d68 | 892 | result = PollBusy(&buf); |
IanBenzMaxim | 24:8942d8478d68 | 893 | |
IanBenzMaxim | 24:8942d8478d68 | 894 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 24:8942d8478d68 | 895 | { |
IanBenzMaxim | 24:8942d8478d68 | 896 | // check for presence detect |
IanBenzMaxim | 24:8942d8478d68 | 897 | if ((buf & STATUS_PPD) != STATUS_PPD) |
IanBenzMaxim | 24:8942d8478d68 | 898 | result = OneWireMaster::OperationFailure; |
IanBenzMaxim | 24:8942d8478d68 | 899 | } |
IanBenzMaxim | 21:00c94aeb533e | 900 | |
IanBenzMaxim | 24:8942d8478d68 | 901 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 902 | } |
IanBenzMaxim | 21:00c94aeb533e | 903 | |
IanBenzMaxim | 21:00c94aeb533e | 904 | OneWireMaster::CmdResult DS2465::Reset(void) |
IanBenzMaxim | 24:8942d8478d68 | 905 | { |
IanBenzMaxim | 21:00c94aeb533e | 906 | // Device Reset |
IanBenzMaxim | 21:00c94aeb533e | 907 | // S AD,0 [A] ADDR_CMD_REG [A] 1WMR [A] Sr AD,1 [A] [SS] A\ P |
IanBenzMaxim | 21:00c94aeb533e | 908 | // [] indicates from slave |
IanBenzMaxim | 21:00c94aeb533e | 909 | // SS status byte to read to verify state |
IanBenzMaxim | 21:00c94aeb533e | 910 | |
IanBenzMaxim | 24:8942d8478d68 | 911 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 24:8942d8478d68 | 912 | uint8_t buf; |
IanBenzMaxim | 21:00c94aeb533e | 913 | |
IanBenzMaxim | 24:8942d8478d68 | 914 | buf = CMD_1WMR; |
IanBenzMaxim | 24:8942d8478d68 | 915 | result = WriteMemory(ADDR_CMD_REG, &buf, 1); |
IanBenzMaxim | 21:00c94aeb533e | 916 | |
IanBenzMaxim | 24:8942d8478d68 | 917 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 24:8942d8478d68 | 918 | result = ReadMemory(ADDR_STATUS_REG, &buf, 1, true); |
IanBenzMaxim | 24:8942d8478d68 | 919 | |
IanBenzMaxim | 24:8942d8478d68 | 920 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 921 | { |
IanBenzMaxim | 24:8942d8478d68 | 922 | if ((buf & 0xF7) != 0x10) |
IanBenzMaxim | 24:8942d8478d68 | 923 | result = OneWireMaster::OperationFailure; |
IanBenzMaxim | 21:00c94aeb533e | 924 | } |
IanBenzMaxim | 24:8942d8478d68 | 925 | |
IanBenzMaxim | 24:8942d8478d68 | 926 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 24:8942d8478d68 | 927 | OWReset(); // do a command to get 1-Wire master reset out of holding state |
IanBenzMaxim | 21:00c94aeb533e | 928 | |
IanBenzMaxim | 24:8942d8478d68 | 929 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 930 | } |
IanBenzMaxim | 21:00c94aeb533e | 931 | |
IanBenzMaxim | 21:00c94aeb533e | 932 | OneWireMaster::CmdResult DS2465::Detect(void) |
IanBenzMaxim | 21:00c94aeb533e | 933 | { |
IanBenzMaxim | 21:00c94aeb533e | 934 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 21:00c94aeb533e | 935 | |
IanBenzMaxim | 21:00c94aeb533e | 936 | // reset DS2465 |
IanBenzMaxim | 21:00c94aeb533e | 937 | result = Reset(); |
IanBenzMaxim | 21:00c94aeb533e | 938 | if (result != OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 939 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 940 | |
IanBenzMaxim | 21:00c94aeb533e | 941 | // default configuration |
IanBenzMaxim | 24:8942d8478d68 | 942 | m_curConfig.reset(); |
IanBenzMaxim | 21:00c94aeb533e | 943 | |
IanBenzMaxim | 21:00c94aeb533e | 944 | // write the default configuration setup |
IanBenzMaxim | 24:8942d8478d68 | 945 | result = WriteConfig(m_curConfig); |
IanBenzMaxim | 21:00c94aeb533e | 946 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 947 | } |