Implementation of 1-Wire with added Alarm Search Functionality
Dependents: Max32630_One_Wire_Interface
OneWire_Masters/DS2465/DS2465.cpp@22:686273e55cdc, 2016-03-21 (annotated)
- Committer:
- j3
- Date:
- Mon Mar 21 21:41:36 2016 +0000
- Revision:
- 22:686273e55cdc
- Parent:
- 21:00c94aeb533e
- Child:
- 24:8942d8478d68
Changed argument to slave(s) constructor from OneWireInterface to OneWireMaster
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 config bits |
IanBenzMaxim | 21:00c94aeb533e | 27 | #define CONFIG_APU 0x01 |
IanBenzMaxim | 21:00c94aeb533e | 28 | #define CONFIG_PDN 0x02 |
IanBenzMaxim | 21:00c94aeb533e | 29 | #define CONFIG_SPU 0x04 |
IanBenzMaxim | 21:00c94aeb533e | 30 | #define CONFIG_1WS 0x08 |
IanBenzMaxim | 21:00c94aeb533e | 31 | |
IanBenzMaxim | 21:00c94aeb533e | 32 | // DS2465 status bits |
IanBenzMaxim | 21:00c94aeb533e | 33 | #define STATUS_1WB 0x01 |
IanBenzMaxim | 21:00c94aeb533e | 34 | #define STATUS_PPD 0x02 |
IanBenzMaxim | 21:00c94aeb533e | 35 | #define STATUS_SD 0x04 |
IanBenzMaxim | 21:00c94aeb533e | 36 | #define STATUS_LL 0x08 |
IanBenzMaxim | 21:00c94aeb533e | 37 | #define STATUS_RST 0x10 |
IanBenzMaxim | 21:00c94aeb533e | 38 | #define STATUS_SBR 0x20 |
IanBenzMaxim | 21:00c94aeb533e | 39 | #define STATUS_TSB 0x40 |
IanBenzMaxim | 21:00c94aeb533e | 40 | #define STATUS_DIR 0x80 |
IanBenzMaxim | 21:00c94aeb533e | 41 | |
IanBenzMaxim | 21:00c94aeb533e | 42 | // delays (if not polling for complete) |
IanBenzMaxim | 21:00c94aeb533e | 43 | #define EEPROM_WRITE_DELAY 30 |
IanBenzMaxim | 21:00c94aeb533e | 44 | #define LOAD_SECRET_DELAY 90 |
IanBenzMaxim | 21:00c94aeb533e | 45 | #define SHA_COMPUTATION_DELAY 5 |
IanBenzMaxim | 21:00c94aeb533e | 46 | |
IanBenzMaxim | 21:00c94aeb533e | 47 | static const int I2C_WRITE_OK = 0; |
IanBenzMaxim | 21:00c94aeb533e | 48 | |
IanBenzMaxim | 21:00c94aeb533e | 49 | DS2465::DS2465(I2C & I2C_interface, unsigned char I2C_address) |
IanBenzMaxim | 21:00c94aeb533e | 50 | : m_I2C_interface(I2C_interface), m_I2C_address(I2C_address) |
IanBenzMaxim | 21:00c94aeb533e | 51 | { |
IanBenzMaxim | 21:00c94aeb533e | 52 | |
IanBenzMaxim | 21:00c94aeb533e | 53 | } |
IanBenzMaxim | 21:00c94aeb533e | 54 | |
IanBenzMaxim | 21:00c94aeb533e | 55 | |
IanBenzMaxim | 21:00c94aeb533e | 56 | |
IanBenzMaxim | 21:00c94aeb533e | 57 | |
IanBenzMaxim | 21:00c94aeb533e | 58 | OneWireMaster::CmdResult DS2465::OWInitMaster() |
IanBenzMaxim | 21:00c94aeb533e | 59 | { |
IanBenzMaxim | 21:00c94aeb533e | 60 | return Detect(); |
IanBenzMaxim | 21:00c94aeb533e | 61 | } |
IanBenzMaxim | 21:00c94aeb533e | 62 | |
IanBenzMaxim | 21:00c94aeb533e | 63 | |
IanBenzMaxim | 21:00c94aeb533e | 64 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 65 | // Compute Next Master Secret DS2465 |
IanBenzMaxim | 21:00c94aeb533e | 66 | // |
IanBenzMaxim | 21:00c94aeb533e | 67 | // 'swap' - 1 if swapping a page into the computation |
IanBenzMaxim | 21:00c94aeb533e | 68 | // 'page' - page number to swap in |
IanBenzMaxim | 21:00c94aeb533e | 69 | // 'region' - (1) first 1/2 page, (2) second 1/2 page, (3) entire page |
IanBenzMaxim | 21:00c94aeb533e | 70 | // |
IanBenzMaxim | 21:00c94aeb533e | 71 | // Returns: true write successful |
IanBenzMaxim | 21:00c94aeb533e | 72 | // false failure to complete read |
IanBenzMaxim | 21:00c94aeb533e | 73 | // |
IanBenzMaxim | 21:00c94aeb533e | 74 | OneWireMaster::CmdResult DS2465::Compute_NextMasterSecret(bool swap, unsigned int pageNum, PageRegion region) |
IanBenzMaxim | 21:00c94aeb533e | 75 | { |
IanBenzMaxim | 21:00c94aeb533e | 76 | uint8_t par; |
IanBenzMaxim | 21:00c94aeb533e | 77 | |
IanBenzMaxim | 21:00c94aeb533e | 78 | // create parameter byte |
IanBenzMaxim | 21:00c94aeb533e | 79 | if (!swap) |
IanBenzMaxim | 21:00c94aeb533e | 80 | par = 0xBF; |
IanBenzMaxim | 21:00c94aeb533e | 81 | else |
IanBenzMaxim | 21:00c94aeb533e | 82 | par = (0xC8 | (pageNum << 4) | region); |
IanBenzMaxim | 21:00c94aeb533e | 83 | |
IanBenzMaxim | 21:00c94aeb533e | 84 | return Write_Command_Reg(CMD_CNMS, par, false); |
IanBenzMaxim | 21:00c94aeb533e | 85 | } |
IanBenzMaxim | 21:00c94aeb533e | 86 | |
IanBenzMaxim | 21:00c94aeb533e | 87 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 88 | // Compute Write MAC DS2465 |
IanBenzMaxim | 21:00c94aeb533e | 89 | // |
IanBenzMaxim | 21:00c94aeb533e | 90 | // 'regwrite' - true if writing to a register, false if regular memory |
IanBenzMaxim | 21:00c94aeb533e | 91 | // 'swap' - true if swapping a page into the computation |
IanBenzMaxim | 21:00c94aeb533e | 92 | // 'page' - page number to swap in |
IanBenzMaxim | 21:00c94aeb533e | 93 | // 'segment' - segment number if swaping |
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_WriteMAC(bool regwrite, bool swap, unsigned int pageNum, unsigned int segmentNum) const |
IanBenzMaxim | 21:00c94aeb533e | 99 | { |
IanBenzMaxim | 21:00c94aeb533e | 100 | uint8_t par; |
IanBenzMaxim | 21:00c94aeb533e | 101 | |
IanBenzMaxim | 21:00c94aeb533e | 102 | // create parameter byte |
IanBenzMaxim | 21:00c94aeb533e | 103 | par = ((regwrite << 7) | (swap << 6) | (pageNum << 4) | segmentNum); |
IanBenzMaxim | 21:00c94aeb533e | 104 | |
IanBenzMaxim | 21:00c94aeb533e | 105 | return Write_Command_Reg(CMD_CSWM, par, false); |
IanBenzMaxim | 21:00c94aeb533e | 106 | } |
IanBenzMaxim | 21:00c94aeb533e | 107 | |
IanBenzMaxim | 21:00c94aeb533e | 108 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 109 | // Compute Slave Authentication MAC DS2465 |
IanBenzMaxim | 21:00c94aeb533e | 110 | // |
IanBenzMaxim | 21:00c94aeb533e | 111 | // 'swap' - true if swapping a page into the computation |
IanBenzMaxim | 21:00c94aeb533e | 112 | // 'page' - page number to swap in |
IanBenzMaxim | 21:00c94aeb533e | 113 | // 'region' - (1) first 1/2 page, (2) second 1/2 page, (3) entire page |
IanBenzMaxim | 21:00c94aeb533e | 114 | // |
IanBenzMaxim | 21:00c94aeb533e | 115 | // Returns: true write successful |
IanBenzMaxim | 21:00c94aeb533e | 116 | // false failure to complete read |
IanBenzMaxim | 21:00c94aeb533e | 117 | // |
IanBenzMaxim | 21:00c94aeb533e | 118 | OneWireMaster::CmdResult DS2465::Compute_AuthMAC(bool swap, unsigned int pageNum, PageRegion region) const |
IanBenzMaxim | 21:00c94aeb533e | 119 | { |
IanBenzMaxim | 21:00c94aeb533e | 120 | uint8_t par; |
IanBenzMaxim | 21:00c94aeb533e | 121 | |
IanBenzMaxim | 21:00c94aeb533e | 122 | // create parameter byte |
IanBenzMaxim | 21:00c94aeb533e | 123 | if (!swap) |
IanBenzMaxim | 21:00c94aeb533e | 124 | par = 0xBF; |
IanBenzMaxim | 21:00c94aeb533e | 125 | else |
IanBenzMaxim | 21:00c94aeb533e | 126 | par = (0xC8 | (pageNum << 4) | region); |
IanBenzMaxim | 21:00c94aeb533e | 127 | |
IanBenzMaxim | 21:00c94aeb533e | 128 | return Write_Command_Reg(CMD_CSAM, par, false); |
IanBenzMaxim | 21:00c94aeb533e | 129 | } |
IanBenzMaxim | 21:00c94aeb533e | 130 | |
IanBenzMaxim | 21:00c94aeb533e | 131 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 132 | // Compute S-Secret on DS2465 |
IanBenzMaxim | 21:00c94aeb533e | 133 | // |
IanBenzMaxim | 21:00c94aeb533e | 134 | // 'swap' - true if swapping a page into the computation |
IanBenzMaxim | 21:00c94aeb533e | 135 | // 'page' - page number to swap in |
IanBenzMaxim | 21:00c94aeb533e | 136 | // 'region' - (1) first 1/2 page, (2) second 1/2 page, (3) entire page |
IanBenzMaxim | 21:00c94aeb533e | 137 | // |
IanBenzMaxim | 21:00c94aeb533e | 138 | // Returns: true write successful |
IanBenzMaxim | 21:00c94aeb533e | 139 | // false failure to complete read |
IanBenzMaxim | 21:00c94aeb533e | 140 | // |
IanBenzMaxim | 21:00c94aeb533e | 141 | OneWireMaster::CmdResult DS2465::Compute_SSecret(bool swap, unsigned int pageNum, PageRegion region) |
IanBenzMaxim | 21:00c94aeb533e | 142 | { |
IanBenzMaxim | 21:00c94aeb533e | 143 | uint8_t par; |
IanBenzMaxim | 21:00c94aeb533e | 144 | |
IanBenzMaxim | 21:00c94aeb533e | 145 | // create parameter byte |
IanBenzMaxim | 21:00c94aeb533e | 146 | if (!swap) |
IanBenzMaxim | 21:00c94aeb533e | 147 | par = 0xBF; |
IanBenzMaxim | 21:00c94aeb533e | 148 | else |
IanBenzMaxim | 21:00c94aeb533e | 149 | par = (0xC8 | (pageNum << 4) | region); |
IanBenzMaxim | 21:00c94aeb533e | 150 | |
IanBenzMaxim | 21:00c94aeb533e | 151 | return Write_Command_Reg(CMD_CSS, par, false); |
IanBenzMaxim | 21:00c94aeb533e | 152 | } |
IanBenzMaxim | 21:00c94aeb533e | 153 | |
IanBenzMaxim | 21:00c94aeb533e | 154 | |
IanBenzMaxim | 21:00c94aeb533e | 155 | |
IanBenzMaxim | 21:00c94aeb533e | 156 | |
IanBenzMaxim | 21:00c94aeb533e | 157 | ISha256MacCoprocessor::CmdResult DS2465::setMasterSecret(const std::uint8_t (&secret)[secret_len]) |
IanBenzMaxim | 21:00c94aeb533e | 158 | { |
IanBenzMaxim | 21:00c94aeb533e | 159 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 21:00c94aeb533e | 160 | result = WriteScratchpad(ADDR_SPAD, secret, secret_len); |
IanBenzMaxim | 21:00c94aeb533e | 161 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 162 | result = CopyScratchpad(1, 0, 1, 0); |
IanBenzMaxim | 21:00c94aeb533e | 163 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 164 | wait_ms(8 * EEPROM_WRITE_DELAY); |
IanBenzMaxim | 21:00c94aeb533e | 165 | return (result == OneWireMaster::Success ? ISha256MacCoprocessor::Success : ISha256MacCoprocessor::OperationFailure); |
IanBenzMaxim | 21:00c94aeb533e | 166 | } |
IanBenzMaxim | 21:00c94aeb533e | 167 | |
IanBenzMaxim | 21:00c94aeb533e | 168 | ISha256MacCoprocessor::CmdResult DS2465::ComputeAndRead_WriteMAC(const std::uint8_t (&WriteMAC_data)[WriteMAC_data_len], std::uint8_t (&mac)[mac_len]) const |
IanBenzMaxim | 21:00c94aeb533e | 169 | { |
IanBenzMaxim | 21:00c94aeb533e | 170 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 21:00c94aeb533e | 171 | // Write input data to scratchpad |
IanBenzMaxim | 21:00c94aeb533e | 172 | result = WriteScratchpad(ADDR_SPAD, WriteMAC_data, WriteMAC_data_len); |
IanBenzMaxim | 21:00c94aeb533e | 173 | // Compute MAC |
IanBenzMaxim | 21:00c94aeb533e | 174 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 175 | result = Compute_WriteMAC(false, false, 0, 0); |
IanBenzMaxim | 21:00c94aeb533e | 176 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 177 | { |
IanBenzMaxim | 21:00c94aeb533e | 178 | wait_ms(SHA_COMPUTATION_DELAY); |
IanBenzMaxim | 21:00c94aeb533e | 179 | // Read MAC from register |
IanBenzMaxim | 21:00c94aeb533e | 180 | result = ReadMemory(ADDR_MAC_READ, mac, mac_len, true); |
IanBenzMaxim | 21:00c94aeb533e | 181 | } |
IanBenzMaxim | 21:00c94aeb533e | 182 | return (result == OneWireMaster::Success ? ISha256MacCoprocessor::Success : ISha256MacCoprocessor::OperationFailure); |
IanBenzMaxim | 21:00c94aeb533e | 183 | } |
IanBenzMaxim | 21:00c94aeb533e | 184 | |
IanBenzMaxim | 21:00c94aeb533e | 185 | ISha256MacCoprocessor::CmdResult DS2465::ComputeAndRead_AuthMAC(const std::uint8_t (&devicePage)[devicePage_len], const std::uint8_t (&challenge)[deviceScratchpad_len], |
IanBenzMaxim | 21:00c94aeb533e | 186 | const std::uint8_t (&AuthMAC_data)[AuthMAC_data_len], std::uint8_t (&mac)[mac_len]) const |
IanBenzMaxim | 21:00c94aeb533e | 187 | { |
IanBenzMaxim | 21:00c94aeb533e | 188 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 21:00c94aeb533e | 189 | int addr = ADDR_SPAD; |
IanBenzMaxim | 21:00c94aeb533e | 190 | // Write input data to scratchpad |
IanBenzMaxim | 21:00c94aeb533e | 191 | result = WriteScratchpad(addr, devicePage, devicePage_len); |
IanBenzMaxim | 21:00c94aeb533e | 192 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 193 | { |
IanBenzMaxim | 21:00c94aeb533e | 194 | addr += devicePage_len; |
IanBenzMaxim | 21:00c94aeb533e | 195 | result = WriteScratchpad(addr, challenge, deviceScratchpad_len); |
IanBenzMaxim | 21:00c94aeb533e | 196 | } |
IanBenzMaxim | 21:00c94aeb533e | 197 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 198 | { |
IanBenzMaxim | 21:00c94aeb533e | 199 | addr += deviceScratchpad_len; |
IanBenzMaxim | 21:00c94aeb533e | 200 | result = WriteScratchpad(addr, AuthMAC_data, AuthMAC_data_len); |
IanBenzMaxim | 21:00c94aeb533e | 201 | } |
IanBenzMaxim | 21:00c94aeb533e | 202 | // Compute MAC |
IanBenzMaxim | 21:00c94aeb533e | 203 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 204 | result = Compute_AuthMAC(false, 0, REGION_FULL_PAGE); |
IanBenzMaxim | 21:00c94aeb533e | 205 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 206 | { |
IanBenzMaxim | 21:00c94aeb533e | 207 | wait_ms(SHA_COMPUTATION_DELAY * 2); |
IanBenzMaxim | 21:00c94aeb533e | 208 | // Read MAC from register |
IanBenzMaxim | 21:00c94aeb533e | 209 | result = ReadMemory(ADDR_MAC_READ, mac, mac_len, true); |
IanBenzMaxim | 21:00c94aeb533e | 210 | } |
IanBenzMaxim | 21:00c94aeb533e | 211 | return (result == OneWireMaster::Success ? ISha256MacCoprocessor::Success : ISha256MacCoprocessor::OperationFailure); |
IanBenzMaxim | 21:00c94aeb533e | 212 | } |
IanBenzMaxim | 21:00c94aeb533e | 213 | |
IanBenzMaxim | 21:00c94aeb533e | 214 | ISha256MacCoprocessor::CmdResult DS2465::Compute_SSecret(const unsigned char (&devicePage)[devicePage_len], const unsigned char (&deviceScratchpad)[deviceScratchpad_len], |
IanBenzMaxim | 21:00c94aeb533e | 215 | const unsigned char (&SSecret_data)[SSecret_data_len]) |
IanBenzMaxim | 21:00c94aeb533e | 216 | { |
IanBenzMaxim | 21:00c94aeb533e | 217 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 21:00c94aeb533e | 218 | int addr = ADDR_SPAD; |
IanBenzMaxim | 21:00c94aeb533e | 219 | // Write input data to scratchpad |
IanBenzMaxim | 21:00c94aeb533e | 220 | result = WriteScratchpad(addr, devicePage, devicePage_len); |
IanBenzMaxim | 21:00c94aeb533e | 221 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 222 | { |
IanBenzMaxim | 21:00c94aeb533e | 223 | addr += devicePage_len; |
IanBenzMaxim | 21:00c94aeb533e | 224 | result = WriteScratchpad(addr, deviceScratchpad, deviceScratchpad_len); |
IanBenzMaxim | 21:00c94aeb533e | 225 | } |
IanBenzMaxim | 21:00c94aeb533e | 226 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 227 | { |
IanBenzMaxim | 21:00c94aeb533e | 228 | addr += deviceScratchpad_len; |
IanBenzMaxim | 21:00c94aeb533e | 229 | result = WriteScratchpad(addr, SSecret_data, SSecret_data_len); |
IanBenzMaxim | 21:00c94aeb533e | 230 | } |
IanBenzMaxim | 21:00c94aeb533e | 231 | // Compute secret |
IanBenzMaxim | 21:00c94aeb533e | 232 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 233 | result = Compute_SSecret(false, 0, REGION_FULL_PAGE); |
IanBenzMaxim | 21:00c94aeb533e | 234 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 235 | wait_ms(SHA_COMPUTATION_DELAY * 2); |
IanBenzMaxim | 21:00c94aeb533e | 236 | return (result == OneWireMaster::Success ? ISha256MacCoprocessor::Success : ISha256MacCoprocessor::OperationFailure); |
IanBenzMaxim | 21:00c94aeb533e | 237 | } |
IanBenzMaxim | 21:00c94aeb533e | 238 | |
IanBenzMaxim | 21:00c94aeb533e | 239 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 240 | // Copy Scratchpad on DS2465 to either secret or memory page |
IanBenzMaxim | 21:00c94aeb533e | 241 | // |
IanBenzMaxim | 21:00c94aeb533e | 242 | // 'dest_secret' - 1 if destination is secret, 0 if memory page |
IanBenzMaxim | 21:00c94aeb533e | 243 | // 'page' - page number if dest_secret=0 |
IanBenzMaxim | 21:00c94aeb533e | 244 | // 'notfull' - 0 if only 4 byte segment, 1 if writing to full page, |
IanBenzMaxim | 21:00c94aeb533e | 245 | // 'seg' - Segment number if full=0. |
IanBenzMaxim | 21:00c94aeb533e | 246 | // |
IanBenzMaxim | 21:00c94aeb533e | 247 | // Returns: true write successful |
IanBenzMaxim | 21:00c94aeb533e | 248 | // false failure to complete read |
IanBenzMaxim | 21:00c94aeb533e | 249 | // |
IanBenzMaxim | 21:00c94aeb533e | 250 | OneWireMaster::CmdResult DS2465::CopyScratchpad(bool dest_secret, unsigned int pageNum, bool notFull, unsigned int segmentNum) |
IanBenzMaxim | 21:00c94aeb533e | 251 | { |
IanBenzMaxim | 21:00c94aeb533e | 252 | uint8_t par; |
IanBenzMaxim | 21:00c94aeb533e | 253 | |
IanBenzMaxim | 21:00c94aeb533e | 254 | // create parameter byte |
IanBenzMaxim | 21:00c94aeb533e | 255 | if (dest_secret) |
IanBenzMaxim | 21:00c94aeb533e | 256 | par = 0; |
IanBenzMaxim | 21:00c94aeb533e | 257 | else |
IanBenzMaxim | 21:00c94aeb533e | 258 | par = (0x80 | (pageNum << 4) | (notFull << 3) | segmentNum); |
IanBenzMaxim | 21:00c94aeb533e | 259 | |
IanBenzMaxim | 21:00c94aeb533e | 260 | return Write_Command_Reg(CMD_CPS, par, false); |
IanBenzMaxim | 21:00c94aeb533e | 261 | } |
IanBenzMaxim | 21:00c94aeb533e | 262 | |
IanBenzMaxim | 21:00c94aeb533e | 263 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 264 | // APU enable or disable |
IanBenzMaxim | 21:00c94aeb533e | 265 | // |
IanBenzMaxim | 21:00c94aeb533e | 266 | // 'readflag' - 1 if reading current configuration |
IanBenzMaxim | 21:00c94aeb533e | 267 | // 'apu_enable' - 1 to enable |
IanBenzMaxim | 21:00c94aeb533e | 268 | // |
IanBenzMaxim | 21:00c94aeb533e | 269 | // Returns: true if write successful, or return configuration value if reading |
IanBenzMaxim | 21:00c94aeb533e | 270 | // |
IanBenzMaxim | 21:00c94aeb533e | 271 | OneWireMaster::CmdResult DS2465::ConfigureAPU(bool apu_enable) |
IanBenzMaxim | 21:00c94aeb533e | 272 | { |
IanBenzMaxim | 21:00c94aeb533e | 273 | // clear power down bit in the global config state |
IanBenzMaxim | 21:00c94aeb533e | 274 | cAPU = apu_enable ? CONFIG_APU : 0; |
IanBenzMaxim | 21:00c94aeb533e | 275 | |
IanBenzMaxim | 21:00c94aeb533e | 276 | // write the new config |
IanBenzMaxim | 21:00c94aeb533e | 277 | return Write_Config(c1WS | cSPU | cPDN | cAPU); |
IanBenzMaxim | 21:00c94aeb533e | 278 | } |
IanBenzMaxim | 21:00c94aeb533e | 279 | |
IanBenzMaxim | 21:00c94aeb533e | 280 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 281 | // Power up 1-Wire using extended function |
IanBenzMaxim | 21:00c94aeb533e | 282 | // |
IanBenzMaxim | 21:00c94aeb533e | 283 | // Returns: true successful |
IanBenzMaxim | 21:00c94aeb533e | 284 | // false failure during communication |
IanBenzMaxim | 21:00c94aeb533e | 285 | // |
IanBenzMaxim | 21:00c94aeb533e | 286 | OneWireMaster::CmdResult DS2465::OWPowerUp(void) |
IanBenzMaxim | 21:00c94aeb533e | 287 | { |
IanBenzMaxim | 21:00c94aeb533e | 288 | OneWireMaster::CmdResult rt; |
IanBenzMaxim | 21:00c94aeb533e | 289 | |
IanBenzMaxim | 21:00c94aeb533e | 290 | // clear power down bit in the global config state |
IanBenzMaxim | 21:00c94aeb533e | 291 | cPDN = 0; |
IanBenzMaxim | 21:00c94aeb533e | 292 | |
IanBenzMaxim | 21:00c94aeb533e | 293 | // write the new config |
IanBenzMaxim | 21:00c94aeb533e | 294 | rt = Write_Config(c1WS | cSPU | cPDN | cAPU); |
IanBenzMaxim | 21:00c94aeb533e | 295 | |
IanBenzMaxim | 21:00c94aeb533e | 296 | // delay 2ms to allow units to power up |
IanBenzMaxim | 21:00c94aeb533e | 297 | wait_ms(2); |
IanBenzMaxim | 21:00c94aeb533e | 298 | |
IanBenzMaxim | 21:00c94aeb533e | 299 | return rt; |
IanBenzMaxim | 21:00c94aeb533e | 300 | } |
IanBenzMaxim | 21:00c94aeb533e | 301 | |
IanBenzMaxim | 21:00c94aeb533e | 302 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 303 | // Power down 1-Wire using extended function |
IanBenzMaxim | 21:00c94aeb533e | 304 | // |
IanBenzMaxim | 21:00c94aeb533e | 305 | // Returns: true successful |
IanBenzMaxim | 21:00c94aeb533e | 306 | // false program voltage not available |
IanBenzMaxim | 21:00c94aeb533e | 307 | // |
IanBenzMaxim | 21:00c94aeb533e | 308 | OneWireMaster::CmdResult DS2465::OWPowerDown(void) |
IanBenzMaxim | 21:00c94aeb533e | 309 | { |
IanBenzMaxim | 21:00c94aeb533e | 310 | // set power down bit in the global config state |
IanBenzMaxim | 21:00c94aeb533e | 311 | cPDN = CONFIG_PDN; |
IanBenzMaxim | 21:00c94aeb533e | 312 | |
IanBenzMaxim | 21:00c94aeb533e | 313 | // write the new config |
IanBenzMaxim | 21:00c94aeb533e | 314 | return Write_Config(c1WS | cSPU | cPDN | cAPU); |
IanBenzMaxim | 21:00c94aeb533e | 315 | } |
IanBenzMaxim | 21:00c94aeb533e | 316 | |
IanBenzMaxim | 21:00c94aeb533e | 317 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 318 | // Send 1 bit of communication to the 1-Wire Net and verify that the |
IanBenzMaxim | 21:00c94aeb533e | 319 | // response matches the 'applyPowerResponse' bit and apply power delivery |
IanBenzMaxim | 21:00c94aeb533e | 320 | // to the 1-Wire net. Note that some implementations may apply the power |
IanBenzMaxim | 21:00c94aeb533e | 321 | // first and then turn it off if the response is incorrect. |
IanBenzMaxim | 21:00c94aeb533e | 322 | // |
IanBenzMaxim | 21:00c94aeb533e | 323 | // 'applyPowerResponse' - 1 bit response to check, if correct then start |
IanBenzMaxim | 21:00c94aeb533e | 324 | // power delivery |
IanBenzMaxim | 21:00c94aeb533e | 325 | // |
IanBenzMaxim | 21:00c94aeb533e | 326 | // Returns: true: bit written and response correct, strong pullup now on |
IanBenzMaxim | 21:00c94aeb533e | 327 | // false: response incorrect |
IanBenzMaxim | 21:00c94aeb533e | 328 | // |
IanBenzMaxim | 21:00c94aeb533e | 329 | OneWireMaster::CmdResult DS2465::OWReadBitPower(uint8_t applyPowerResponse) |
IanBenzMaxim | 21:00c94aeb533e | 330 | { |
IanBenzMaxim | 21:00c94aeb533e | 331 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 21:00c94aeb533e | 332 | uint8_t rdbit; |
IanBenzMaxim | 21:00c94aeb533e | 333 | |
IanBenzMaxim | 21:00c94aeb533e | 334 | // set strong pull-up enable |
IanBenzMaxim | 21:00c94aeb533e | 335 | cSPU = CONFIG_SPU; |
IanBenzMaxim | 21:00c94aeb533e | 336 | |
IanBenzMaxim | 21:00c94aeb533e | 337 | // write the new config |
IanBenzMaxim | 21:00c94aeb533e | 338 | result = Write_Config(c1WS | cSPU | cPDN | cAPU); |
IanBenzMaxim | 21:00c94aeb533e | 339 | if (result != OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 340 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 341 | |
IanBenzMaxim | 21:00c94aeb533e | 342 | // perform read bit |
IanBenzMaxim | 21:00c94aeb533e | 343 | result = OWReadBit(rdbit); |
IanBenzMaxim | 21:00c94aeb533e | 344 | if (result != OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 345 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 346 | |
IanBenzMaxim | 21:00c94aeb533e | 347 | // check if response was correct, if not then turn off strong pull-up |
IanBenzMaxim | 21:00c94aeb533e | 348 | if (rdbit != applyPowerResponse) |
IanBenzMaxim | 21:00c94aeb533e | 349 | { |
IanBenzMaxim | 21:00c94aeb533e | 350 | OWLevel(LEVEL_NORMAL); |
IanBenzMaxim | 21:00c94aeb533e | 351 | return OneWireMaster::OperationFailure; |
IanBenzMaxim | 21:00c94aeb533e | 352 | } |
IanBenzMaxim | 21:00c94aeb533e | 353 | |
IanBenzMaxim | 21:00c94aeb533e | 354 | return OneWireMaster::Success; |
IanBenzMaxim | 21:00c94aeb533e | 355 | } |
IanBenzMaxim | 21:00c94aeb533e | 356 | |
IanBenzMaxim | 21:00c94aeb533e | 357 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 358 | // Read 8 bits of communication from the 1-Wire Net. After the |
IanBenzMaxim | 21:00c94aeb533e | 359 | // 8 bits are read then change the level of the 1-Wire net. |
IanBenzMaxim | 21:00c94aeb533e | 360 | // |
IanBenzMaxim | 21:00c94aeb533e | 361 | // Returns: 8 bits read from 1-Wire Net |
IanBenzMaxim | 21:00c94aeb533e | 362 | // |
IanBenzMaxim | 21:00c94aeb533e | 363 | OneWireMaster::CmdResult DS2465::OWReadBytePower(uint8_t & recvbyte) |
IanBenzMaxim | 21:00c94aeb533e | 364 | { |
IanBenzMaxim | 21:00c94aeb533e | 365 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 21:00c94aeb533e | 366 | |
IanBenzMaxim | 21:00c94aeb533e | 367 | // set strong pull-up enable |
IanBenzMaxim | 21:00c94aeb533e | 368 | cSPU = CONFIG_SPU; |
IanBenzMaxim | 21:00c94aeb533e | 369 | |
IanBenzMaxim | 21:00c94aeb533e | 370 | // write the new config |
IanBenzMaxim | 21:00c94aeb533e | 371 | result = Write_Config(c1WS | cSPU | cPDN | cAPU); |
IanBenzMaxim | 21:00c94aeb533e | 372 | if (result != OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 373 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 374 | |
IanBenzMaxim | 21:00c94aeb533e | 375 | // do the read byte |
IanBenzMaxim | 21:00c94aeb533e | 376 | result = OWReadByte(recvbyte); |
IanBenzMaxim | 21:00c94aeb533e | 377 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 378 | } |
IanBenzMaxim | 21:00c94aeb533e | 379 | |
IanBenzMaxim | 21:00c94aeb533e | 380 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 381 | // Send 8 bits of communication to the 1-Wire Net and verify that the |
IanBenzMaxim | 21:00c94aeb533e | 382 | // 8 bits read from the 1-Wire Net is the same (write operation). |
IanBenzMaxim | 21:00c94aeb533e | 383 | // The parameter 'sendbyte' least significant 8 bits are used. After the |
IanBenzMaxim | 21:00c94aeb533e | 384 | // 8 bits are sent change the level of the 1-Wire net. |
IanBenzMaxim | 21:00c94aeb533e | 385 | // |
IanBenzMaxim | 21:00c94aeb533e | 386 | // 'sendbyte' - 8 bits to send (least significant bit) |
IanBenzMaxim | 21:00c94aeb533e | 387 | // |
IanBenzMaxim | 21:00c94aeb533e | 388 | OneWireMaster::CmdResult DS2465::OWWriteBytePower(uint8_t sendbyte) |
IanBenzMaxim | 21:00c94aeb533e | 389 | { |
IanBenzMaxim | 21:00c94aeb533e | 390 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 21:00c94aeb533e | 391 | |
IanBenzMaxim | 21:00c94aeb533e | 392 | // set strong pull-up enable |
IanBenzMaxim | 21:00c94aeb533e | 393 | cSPU = CONFIG_SPU; |
IanBenzMaxim | 21:00c94aeb533e | 394 | |
IanBenzMaxim | 21:00c94aeb533e | 395 | // write the new config |
IanBenzMaxim | 21:00c94aeb533e | 396 | result = Write_Config(c1WS | cSPU | cPDN | cAPU); |
IanBenzMaxim | 21:00c94aeb533e | 397 | if (result != OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 398 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 399 | |
IanBenzMaxim | 21:00c94aeb533e | 400 | // perform write byte |
IanBenzMaxim | 21:00c94aeb533e | 401 | return OWWriteByte(sendbyte); |
IanBenzMaxim | 21:00c94aeb533e | 402 | } |
IanBenzMaxim | 21:00c94aeb533e | 403 | |
IanBenzMaxim | 21:00c94aeb533e | 404 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 405 | // Set the 1-Wire Net line level pull-up to normal. The DS2465 does only |
IanBenzMaxim | 21:00c94aeb533e | 406 | // allows enabling strong pull-up on a bit or byte event. Consequently this |
IanBenzMaxim | 21:00c94aeb533e | 407 | // function only allows the MODE_STANDARD argument. To enable strong pull-up |
IanBenzMaxim | 21:00c94aeb533e | 408 | // use OWWriteBytePower or OWReadBitPower. |
IanBenzMaxim | 21:00c94aeb533e | 409 | // |
IanBenzMaxim | 21:00c94aeb533e | 410 | // 'new_level' - new level defined as |
IanBenzMaxim | 21:00c94aeb533e | 411 | // MODE_STANDARD 0x00 |
IanBenzMaxim | 21:00c94aeb533e | 412 | // |
IanBenzMaxim | 21:00c94aeb533e | 413 | // Returns: current 1-Wire Net level |
IanBenzMaxim | 21:00c94aeb533e | 414 | // |
IanBenzMaxim | 21:00c94aeb533e | 415 | OneWireMaster::CmdResult DS2465::OWLevel(OW_LEVEL new_level) |
IanBenzMaxim | 21:00c94aeb533e | 416 | { |
IanBenzMaxim | 21:00c94aeb533e | 417 | // function only will turn back to non-strong pull-up |
IanBenzMaxim | 21:00c94aeb533e | 418 | if (new_level != LEVEL_NORMAL) |
IanBenzMaxim | 21:00c94aeb533e | 419 | return OneWireMaster::OperationFailure; |
IanBenzMaxim | 21:00c94aeb533e | 420 | |
IanBenzMaxim | 21:00c94aeb533e | 421 | // clear the strong pull-up bit in the global config state |
IanBenzMaxim | 21:00c94aeb533e | 422 | cSPU = 0; |
IanBenzMaxim | 21:00c94aeb533e | 423 | |
IanBenzMaxim | 21:00c94aeb533e | 424 | // write the new config |
IanBenzMaxim | 21:00c94aeb533e | 425 | return Write_Config(c1WS | cSPU | cPDN | cAPU); |
IanBenzMaxim | 21:00c94aeb533e | 426 | } |
IanBenzMaxim | 21:00c94aeb533e | 427 | |
IanBenzMaxim | 21:00c94aeb533e | 428 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 429 | // The 'OWOverdriveMatchROM' function does an overdrive Match-ROM using the |
IanBenzMaxim | 21:00c94aeb533e | 430 | // global ROM_NO device |
IanBenzMaxim | 21:00c94aeb533e | 431 | // |
IanBenzMaxim | 21:00c94aeb533e | 432 | // Returns: true (1) : OWReset successful and match rom sent. |
IanBenzMaxim | 21:00c94aeb533e | 433 | // false (0): OWReset did not have presence |
IanBenzMaxim | 21:00c94aeb533e | 434 | // |
IanBenzMaxim | 21:00c94aeb533e | 435 | OneWireMaster::CmdResult DS2465::OWOverdriveMatchROM(const RomId & romId) |
IanBenzMaxim | 21:00c94aeb533e | 436 | { |
IanBenzMaxim | 21:00c94aeb533e | 437 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 21:00c94aeb533e | 438 | // use overdrive MatchROM |
IanBenzMaxim | 21:00c94aeb533e | 439 | OWSpeed(SPEED_STANDARD); |
IanBenzMaxim | 21:00c94aeb533e | 440 | result = OWReset(); |
IanBenzMaxim | 21:00c94aeb533e | 441 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 442 | { |
IanBenzMaxim | 21:00c94aeb533e | 443 | result = OWWriteByte(0x69); |
IanBenzMaxim | 21:00c94aeb533e | 444 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 445 | { |
IanBenzMaxim | 21:00c94aeb533e | 446 | OWSpeed(SPEED_OVERDRIVE); |
IanBenzMaxim | 21:00c94aeb533e | 447 | // send ROM |
IanBenzMaxim | 21:00c94aeb533e | 448 | result = OWWriteBlock(false, romId, RomId::byteLen); |
IanBenzMaxim | 21:00c94aeb533e | 449 | } |
IanBenzMaxim | 21:00c94aeb533e | 450 | } |
IanBenzMaxim | 21:00c94aeb533e | 451 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 452 | } |
IanBenzMaxim | 21:00c94aeb533e | 453 | |
IanBenzMaxim | 21:00c94aeb533e | 454 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 455 | // The 'OWMatchROM' function does a Match-ROM using the global ROM_NO device |
IanBenzMaxim | 21:00c94aeb533e | 456 | // |
IanBenzMaxim | 21:00c94aeb533e | 457 | // Returns: true (1) : OWReset successful and match rom sent. |
IanBenzMaxim | 21:00c94aeb533e | 458 | // false (0): OWReset did not have presence |
IanBenzMaxim | 21:00c94aeb533e | 459 | // |
IanBenzMaxim | 21:00c94aeb533e | 460 | OneWireMaster::CmdResult DS2465::OWMatchROM(const RomId & romId) |
IanBenzMaxim | 21:00c94aeb533e | 461 | { |
IanBenzMaxim | 21:00c94aeb533e | 462 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 21:00c94aeb533e | 463 | uint8_t buf[1 + RomId::byteLen]; |
IanBenzMaxim | 21:00c94aeb533e | 464 | |
IanBenzMaxim | 21:00c94aeb533e | 465 | // use MatchROM |
IanBenzMaxim | 21:00c94aeb533e | 466 | result = OWReset(); |
IanBenzMaxim | 21:00c94aeb533e | 467 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 468 | { |
IanBenzMaxim | 21:00c94aeb533e | 469 | buf[0] = 0x55; |
IanBenzMaxim | 21:00c94aeb533e | 470 | std::memcpy(&buf[1], romId, RomId::byteLen); |
IanBenzMaxim | 21:00c94aeb533e | 471 | // send command and rom |
IanBenzMaxim | 21:00c94aeb533e | 472 | result = OWWriteBlock(false, buf, 1 + RomId::byteLen); |
IanBenzMaxim | 21:00c94aeb533e | 473 | } |
IanBenzMaxim | 21:00c94aeb533e | 474 | |
IanBenzMaxim | 21:00c94aeb533e | 475 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 476 | } |
IanBenzMaxim | 21:00c94aeb533e | 477 | |
IanBenzMaxim | 21:00c94aeb533e | 478 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 479 | // Setup the search to skip the current device type on the next call |
IanBenzMaxim | 21:00c94aeb533e | 480 | // to OWNext(). |
IanBenzMaxim | 21:00c94aeb533e | 481 | // |
IanBenzMaxim | 21:00c94aeb533e | 482 | void DS2465::OWFamilySkipSetup(void) |
IanBenzMaxim | 21:00c94aeb533e | 483 | { |
IanBenzMaxim | 21:00c94aeb533e | 484 | // set the Last discrepancy to last family discrepancy |
IanBenzMaxim | 21:00c94aeb533e | 485 | m_lastDiscrepancy = m_lastFamilyDiscrepancy; |
IanBenzMaxim | 21:00c94aeb533e | 486 | |
IanBenzMaxim | 21:00c94aeb533e | 487 | // clear the last family discrpepancy |
IanBenzMaxim | 21:00c94aeb533e | 488 | m_lastFamilyDiscrepancy = 0; |
IanBenzMaxim | 21:00c94aeb533e | 489 | |
IanBenzMaxim | 21:00c94aeb533e | 490 | // check for end of list |
IanBenzMaxim | 21:00c94aeb533e | 491 | if (m_lastDiscrepancy == 0) |
IanBenzMaxim | 21:00c94aeb533e | 492 | m_lastDeviceFlag = true; |
IanBenzMaxim | 21:00c94aeb533e | 493 | } |
IanBenzMaxim | 21:00c94aeb533e | 494 | |
IanBenzMaxim | 21:00c94aeb533e | 495 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 496 | // Setup the search to find the device type 'family_code' on the next call |
IanBenzMaxim | 21:00c94aeb533e | 497 | // to OWNext() if it is present. |
IanBenzMaxim | 21:00c94aeb533e | 498 | // |
IanBenzMaxim | 21:00c94aeb533e | 499 | void DS2465::OWTargetSetup(RomId & romId) |
IanBenzMaxim | 21:00c94aeb533e | 500 | { |
IanBenzMaxim | 21:00c94aeb533e | 501 | // set the search state to find SearchFamily type devices |
IanBenzMaxim | 21:00c94aeb533e | 502 | for (int i = 1; i < 8; i++) |
IanBenzMaxim | 21:00c94aeb533e | 503 | romId[i] = 0; |
IanBenzMaxim | 21:00c94aeb533e | 504 | m_lastDiscrepancy = 64; |
IanBenzMaxim | 21:00c94aeb533e | 505 | m_lastFamilyDiscrepancy = 0; |
IanBenzMaxim | 21:00c94aeb533e | 506 | m_lastDeviceFlag = false; |
IanBenzMaxim | 21:00c94aeb533e | 507 | } |
IanBenzMaxim | 21:00c94aeb533e | 508 | |
IanBenzMaxim | 21:00c94aeb533e | 509 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 510 | // Verify the device with the ROM number in ROM_NO buffer is present. |
IanBenzMaxim | 21:00c94aeb533e | 511 | // Return true : device verified present |
IanBenzMaxim | 21:00c94aeb533e | 512 | // false : device not present |
IanBenzMaxim | 21:00c94aeb533e | 513 | // |
IanBenzMaxim | 21:00c94aeb533e | 514 | OneWireMaster::CmdResult DS2465::OWVerify(const RomId & romId) |
IanBenzMaxim | 21:00c94aeb533e | 515 | { |
IanBenzMaxim | 21:00c94aeb533e | 516 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 21:00c94aeb533e | 517 | RomId romIdCopy(romId); |
IanBenzMaxim | 21:00c94aeb533e | 518 | int ld_backup, ldf_backup, lfd_backup; |
IanBenzMaxim | 21:00c94aeb533e | 519 | |
IanBenzMaxim | 21:00c94aeb533e | 520 | // keep a backup copy of the current state |
IanBenzMaxim | 21:00c94aeb533e | 521 | ld_backup = m_lastDiscrepancy; |
IanBenzMaxim | 21:00c94aeb533e | 522 | ldf_backup = m_lastDeviceFlag; |
IanBenzMaxim | 21:00c94aeb533e | 523 | lfd_backup = m_lastFamilyDiscrepancy; |
IanBenzMaxim | 21:00c94aeb533e | 524 | |
IanBenzMaxim | 21:00c94aeb533e | 525 | // set search to find the same device |
IanBenzMaxim | 21:00c94aeb533e | 526 | m_lastDiscrepancy = 64; |
IanBenzMaxim | 21:00c94aeb533e | 527 | m_lastDeviceFlag = false; |
IanBenzMaxim | 21:00c94aeb533e | 528 | |
IanBenzMaxim | 21:00c94aeb533e | 529 | result = OWSearch(romIdCopy); |
IanBenzMaxim | 21:00c94aeb533e | 530 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 531 | { |
IanBenzMaxim | 21:00c94aeb533e | 532 | // check if same device found |
IanBenzMaxim | 21:00c94aeb533e | 533 | if (romId != romIdCopy) |
IanBenzMaxim | 21:00c94aeb533e | 534 | { |
IanBenzMaxim | 21:00c94aeb533e | 535 | result = OneWireMaster::OperationFailure; |
IanBenzMaxim | 21:00c94aeb533e | 536 | } |
IanBenzMaxim | 21:00c94aeb533e | 537 | } |
IanBenzMaxim | 21:00c94aeb533e | 538 | |
IanBenzMaxim | 21:00c94aeb533e | 539 | // restore the search state |
IanBenzMaxim | 21:00c94aeb533e | 540 | m_lastDiscrepancy = ld_backup; |
IanBenzMaxim | 21:00c94aeb533e | 541 | m_lastDeviceFlag = ldf_backup; |
IanBenzMaxim | 21:00c94aeb533e | 542 | m_lastFamilyDiscrepancy = lfd_backup; |
IanBenzMaxim | 21:00c94aeb533e | 543 | |
IanBenzMaxim | 21:00c94aeb533e | 544 | // return the result of the verify |
IanBenzMaxim | 21:00c94aeb533e | 545 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 546 | } |
IanBenzMaxim | 21:00c94aeb533e | 547 | |
IanBenzMaxim | 21:00c94aeb533e | 548 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 549 | // Find the 'next' devices on the 1-Wire network |
IanBenzMaxim | 21:00c94aeb533e | 550 | // Return true : device found, ROM number in ROM_NO buffer |
IanBenzMaxim | 21:00c94aeb533e | 551 | // false : device not found, end of search |
IanBenzMaxim | 21:00c94aeb533e | 552 | // |
IanBenzMaxim | 21:00c94aeb533e | 553 | OneWireMaster::CmdResult DS2465::OWNext(RomId & romId) |
IanBenzMaxim | 21:00c94aeb533e | 554 | { |
IanBenzMaxim | 21:00c94aeb533e | 555 | // leave the search state alone |
IanBenzMaxim | 21:00c94aeb533e | 556 | return OWSearch(romId); |
IanBenzMaxim | 21:00c94aeb533e | 557 | } |
IanBenzMaxim | 21:00c94aeb533e | 558 | |
IanBenzMaxim | 21:00c94aeb533e | 559 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 560 | // Set the 1-Wire Net communication speed. |
IanBenzMaxim | 21:00c94aeb533e | 561 | // |
IanBenzMaxim | 21:00c94aeb533e | 562 | // 'new_speed' - new speed defined as |
IanBenzMaxim | 21:00c94aeb533e | 563 | // MODE_STANDARD 0x00 |
IanBenzMaxim | 21:00c94aeb533e | 564 | // MODE_OVERDRIVE 0x01 |
IanBenzMaxim | 21:00c94aeb533e | 565 | // |
IanBenzMaxim | 21:00c94aeb533e | 566 | // Returns: current 1-Wire Net speed |
IanBenzMaxim | 21:00c94aeb533e | 567 | // |
IanBenzMaxim | 21:00c94aeb533e | 568 | OneWireMaster::CmdResult DS2465::OWSpeed(OW_SPEED new_speed) |
IanBenzMaxim | 21:00c94aeb533e | 569 | { |
IanBenzMaxim | 21:00c94aeb533e | 570 | // set the speed |
IanBenzMaxim | 21:00c94aeb533e | 571 | if (new_speed == SPEED_OVERDRIVE) |
IanBenzMaxim | 21:00c94aeb533e | 572 | c1WS = CONFIG_1WS; |
IanBenzMaxim | 21:00c94aeb533e | 573 | else |
IanBenzMaxim | 21:00c94aeb533e | 574 | c1WS = 0; |
IanBenzMaxim | 21:00c94aeb533e | 575 | |
IanBenzMaxim | 21:00c94aeb533e | 576 | // write the new config |
IanBenzMaxim | 21:00c94aeb533e | 577 | return Write_Config(c1WS | cSPU | cPDN | cAPU); |
IanBenzMaxim | 21:00c94aeb533e | 578 | } |
IanBenzMaxim | 21:00c94aeb533e | 579 | |
IanBenzMaxim | 21:00c94aeb533e | 580 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 581 | // The 'OWOverdriveSkipROM' function does an Overdrive skip-ROM. Ignores |
IanBenzMaxim | 21:00c94aeb533e | 582 | // result from standard speed OWReset(). |
IanBenzMaxim | 21:00c94aeb533e | 583 | // |
IanBenzMaxim | 21:00c94aeb533e | 584 | // Returns: true (1) : OWReset and skip rom sent. |
IanBenzMaxim | 21:00c94aeb533e | 585 | // false (0): Could not change to overdrive |
IanBenzMaxim | 21:00c94aeb533e | 586 | // |
IanBenzMaxim | 21:00c94aeb533e | 587 | OneWireMaster::CmdResult DS2465::OWOverdriveSkipROM(void) |
IanBenzMaxim | 21:00c94aeb533e | 588 | { |
IanBenzMaxim | 21:00c94aeb533e | 589 | OneWireMaster::CmdResult result = OWSpeed(SPEED_STANDARD); |
IanBenzMaxim | 21:00c94aeb533e | 590 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 591 | result = OWReset(); |
IanBenzMaxim | 21:00c94aeb533e | 592 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 593 | result = OWWriteByte(0x3C); |
IanBenzMaxim | 21:00c94aeb533e | 594 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 595 | result = OWSpeed(SPEED_OVERDRIVE); |
IanBenzMaxim | 21:00c94aeb533e | 596 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 597 | } |
IanBenzMaxim | 21:00c94aeb533e | 598 | |
IanBenzMaxim | 21:00c94aeb533e | 599 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 600 | // The 'OWResume' function does a Resume command 0xA5. |
IanBenzMaxim | 21:00c94aeb533e | 601 | // |
IanBenzMaxim | 21:00c94aeb533e | 602 | // Returns: true (1) : OWReset successful and RESUME sent. |
IanBenzMaxim | 21:00c94aeb533e | 603 | // false (0): OWReset did not have presence |
IanBenzMaxim | 21:00c94aeb533e | 604 | // |
IanBenzMaxim | 21:00c94aeb533e | 605 | OneWireMaster::CmdResult DS2465::OWResume(void) |
IanBenzMaxim | 21:00c94aeb533e | 606 | { |
IanBenzMaxim | 21:00c94aeb533e | 607 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 21:00c94aeb533e | 608 | result = OWReset(); |
IanBenzMaxim | 21:00c94aeb533e | 609 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 610 | { |
IanBenzMaxim | 21:00c94aeb533e | 611 | result = OWWriteByte(0xA5); |
IanBenzMaxim | 21:00c94aeb533e | 612 | } |
IanBenzMaxim | 21:00c94aeb533e | 613 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 614 | } |
IanBenzMaxim | 21:00c94aeb533e | 615 | |
IanBenzMaxim | 21:00c94aeb533e | 616 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 617 | // The 'OWSkipROM' function does a skip-ROM. This function |
IanBenzMaxim | 21:00c94aeb533e | 618 | // uses the Skip-ROM function CCh. |
IanBenzMaxim | 21:00c94aeb533e | 619 | // |
IanBenzMaxim | 21:00c94aeb533e | 620 | // Returns: true (1) : OWReset successful and skip rom sent. |
IanBenzMaxim | 21:00c94aeb533e | 621 | // false (0): OWReset did not have presence |
IanBenzMaxim | 21:00c94aeb533e | 622 | // |
IanBenzMaxim | 21:00c94aeb533e | 623 | OneWireMaster::CmdResult DS2465::OWSkipROM(void) |
IanBenzMaxim | 21:00c94aeb533e | 624 | { |
IanBenzMaxim | 21:00c94aeb533e | 625 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 21:00c94aeb533e | 626 | result = OWReset(); |
IanBenzMaxim | 21:00c94aeb533e | 627 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 628 | { |
IanBenzMaxim | 21:00c94aeb533e | 629 | result = OWWriteByte(0xCC); |
IanBenzMaxim | 21:00c94aeb533e | 630 | } |
IanBenzMaxim | 21:00c94aeb533e | 631 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 632 | } |
IanBenzMaxim | 21:00c94aeb533e | 633 | |
IanBenzMaxim | 21:00c94aeb533e | 634 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 635 | // The 'OWReadROM' function does a Read-ROM. This function |
IanBenzMaxim | 21:00c94aeb533e | 636 | // uses the read-ROM function 33h to read a ROM number and verify CRC8. |
IanBenzMaxim | 21:00c94aeb533e | 637 | // |
IanBenzMaxim | 21:00c94aeb533e | 638 | // Returns: true (1) : OWReset successful and Serial Number placed |
IanBenzMaxim | 21:00c94aeb533e | 639 | // in the global ROM, CRC8 valid |
IanBenzMaxim | 21:00c94aeb533e | 640 | // false (0): OWReset did not have presence or CRC8 invalid |
IanBenzMaxim | 21:00c94aeb533e | 641 | // |
IanBenzMaxim | 21:00c94aeb533e | 642 | OneWireMaster::CmdResult DS2465::OWReadROM(RomId & romId) |
IanBenzMaxim | 21:00c94aeb533e | 643 | { |
IanBenzMaxim | 21:00c94aeb533e | 644 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 21:00c94aeb533e | 645 | uint8_t buf[2 + RomId::byteLen]; |
IanBenzMaxim | 21:00c94aeb533e | 646 | |
IanBenzMaxim | 21:00c94aeb533e | 647 | result = OWReset(); |
IanBenzMaxim | 21:00c94aeb533e | 648 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 649 | result = OWWriteByte(0x33); // READ ROM |
IanBenzMaxim | 21:00c94aeb533e | 650 | |
IanBenzMaxim | 21:00c94aeb533e | 651 | // read the ROM |
IanBenzMaxim | 21:00c94aeb533e | 652 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 653 | result = OWReadBlock(buf, RomId::byteLen); |
IanBenzMaxim | 21:00c94aeb533e | 654 | |
IanBenzMaxim | 21:00c94aeb533e | 655 | // verify CRC8 |
IanBenzMaxim | 21:00c94aeb533e | 656 | if ((result == OneWireMaster::Success) && (RomId::calculateCRC8(buf, RomId::byteLen) == 0) && (buf[1] != 0)) |
IanBenzMaxim | 21:00c94aeb533e | 657 | romId = RomId(reinterpret_cast<std::uint8_t (&)[RomId::byteLen]>(buf[0])); |
IanBenzMaxim | 21:00c94aeb533e | 658 | |
IanBenzMaxim | 21:00c94aeb533e | 659 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 660 | } |
IanBenzMaxim | 21:00c94aeb533e | 661 | |
IanBenzMaxim | 21:00c94aeb533e | 662 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 663 | // Use the DS2465 help command '1-Wire triplet' to perform one bit of a 1-Wire |
IanBenzMaxim | 21:00c94aeb533e | 664 | // search. This command does two read bits and one write bit. The write bit |
IanBenzMaxim | 21:00c94aeb533e | 665 | // is either the default direction (all device have same bit) or in case of |
IanBenzMaxim | 21:00c94aeb533e | 666 | // a discripancy, the 'search_direction' parameter is used. |
IanBenzMaxim | 21:00c94aeb533e | 667 | // |
j3 | 22:686273e55cdc | 668 | // Returns � The DS2465 status byte result from the triplet command |
IanBenzMaxim | 21:00c94aeb533e | 669 | // |
IanBenzMaxim | 21:00c94aeb533e | 670 | OneWireMaster::CmdResult DS2465::Triplet(Direction search_direction, uint8_t & status) |
IanBenzMaxim | 21:00c94aeb533e | 671 | { |
IanBenzMaxim | 21:00c94aeb533e | 672 | int poll_count = 0; |
IanBenzMaxim | 21:00c94aeb533e | 673 | |
IanBenzMaxim | 21:00c94aeb533e | 674 | // 1-Wire Triplet (Case B) |
IanBenzMaxim | 21:00c94aeb533e | 675 | // S AD,0 [A] 1WT [A] SS [A] Sr AD,1 [A] [Status] A [Status] A\ P |
IanBenzMaxim | 21:00c94aeb533e | 676 | // \--------/ |
IanBenzMaxim | 21:00c94aeb533e | 677 | // Repeat until 1WB bit has changed to 0 |
IanBenzMaxim | 21:00c94aeb533e | 678 | // [] indicates from slave |
IanBenzMaxim | 21:00c94aeb533e | 679 | // SS indicates byte containing search direction bit value in msbit |
IanBenzMaxim | 21:00c94aeb533e | 680 | |
IanBenzMaxim | 21:00c94aeb533e | 681 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 682 | if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 683 | { |
IanBenzMaxim | 21:00c94aeb533e | 684 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 685 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 686 | } |
IanBenzMaxim | 21:00c94aeb533e | 687 | if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 688 | { |
IanBenzMaxim | 21:00c94aeb533e | 689 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 690 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 691 | } |
IanBenzMaxim | 21:00c94aeb533e | 692 | if (m_I2C_interface.write(CMD_1WT) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 693 | { |
IanBenzMaxim | 21:00c94aeb533e | 694 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 695 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 696 | } |
IanBenzMaxim | 21:00c94aeb533e | 697 | if (m_I2C_interface.write((unsigned char)((search_direction == DIRECTION_WRITE_ONE) ? 0x80 : 0x00)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 698 | { |
IanBenzMaxim | 21:00c94aeb533e | 699 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 700 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 701 | } |
IanBenzMaxim | 21:00c94aeb533e | 702 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 703 | if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_READ)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 704 | { |
IanBenzMaxim | 21:00c94aeb533e | 705 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 706 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 707 | } |
IanBenzMaxim | 21:00c94aeb533e | 708 | |
IanBenzMaxim | 21:00c94aeb533e | 709 | // loop checking 1WB bit for completion of 1-Wire operation |
IanBenzMaxim | 21:00c94aeb533e | 710 | // abort if poll limit reached |
IanBenzMaxim | 21:00c94aeb533e | 711 | status = STATUS_1WB; |
IanBenzMaxim | 21:00c94aeb533e | 712 | while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT)) |
IanBenzMaxim | 21:00c94aeb533e | 713 | { |
IanBenzMaxim | 21:00c94aeb533e | 714 | status = m_I2C_interface.read(status & STATUS_1WB); |
IanBenzMaxim | 21:00c94aeb533e | 715 | } |
IanBenzMaxim | 21:00c94aeb533e | 716 | |
IanBenzMaxim | 21:00c94aeb533e | 717 | // one last read with NACK |
IanBenzMaxim | 21:00c94aeb533e | 718 | m_I2C_interface.read(m_I2C_interface.NoACK); |
IanBenzMaxim | 21:00c94aeb533e | 719 | |
IanBenzMaxim | 21:00c94aeb533e | 720 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 721 | |
IanBenzMaxim | 21:00c94aeb533e | 722 | // check for failure due to poll limit reached |
IanBenzMaxim | 21:00c94aeb533e | 723 | if (poll_count >= POLL_LIMIT) |
IanBenzMaxim | 21:00c94aeb533e | 724 | { |
IanBenzMaxim | 21:00c94aeb533e | 725 | // handle error |
IanBenzMaxim | 21:00c94aeb533e | 726 | // ... |
IanBenzMaxim | 21:00c94aeb533e | 727 | Reset(); |
IanBenzMaxim | 21:00c94aeb533e | 728 | return OneWireMaster::TimeoutError; |
IanBenzMaxim | 21:00c94aeb533e | 729 | } |
IanBenzMaxim | 21:00c94aeb533e | 730 | |
IanBenzMaxim | 21:00c94aeb533e | 731 | // return status byte |
IanBenzMaxim | 21:00c94aeb533e | 732 | return OneWireMaster::Success; |
IanBenzMaxim | 21:00c94aeb533e | 733 | } |
IanBenzMaxim | 21:00c94aeb533e | 734 | |
IanBenzMaxim | 21:00c94aeb533e | 735 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 736 | // The 'OWSearch' function does a general search. This function |
IanBenzMaxim | 21:00c94aeb533e | 737 | // continues from the previos search state. The search state |
IanBenzMaxim | 21:00c94aeb533e | 738 | // can be reset by using the 'OWFirst' function. |
IanBenzMaxim | 21:00c94aeb533e | 739 | // This function contains one parameter 'alarm_only'. |
IanBenzMaxim | 21:00c94aeb533e | 740 | // When 'alarm_only' is true (1) the find alarm command |
IanBenzMaxim | 21:00c94aeb533e | 741 | // 0xEC is sent instead of the normal search command 0xF0. |
IanBenzMaxim | 21:00c94aeb533e | 742 | // Using the find alarm command 0xEC will limit the search to only |
IanBenzMaxim | 21:00c94aeb533e | 743 | // 1-Wire devices that are in an 'alarm' state. |
IanBenzMaxim | 21:00c94aeb533e | 744 | // |
IanBenzMaxim | 21:00c94aeb533e | 745 | // Returns: true (1) : when a 1-Wire device was found and it's |
IanBenzMaxim | 21:00c94aeb533e | 746 | // Serial Number placed in the global ROM |
IanBenzMaxim | 21:00c94aeb533e | 747 | // false (0): when no new device was found. Either the |
IanBenzMaxim | 21:00c94aeb533e | 748 | // last search was the last device or there |
IanBenzMaxim | 21:00c94aeb533e | 749 | // are no devices on the 1-Wire Net. |
IanBenzMaxim | 21:00c94aeb533e | 750 | // |
IanBenzMaxim | 21:00c94aeb533e | 751 | OneWireMaster::CmdResult DS2465::OWSearch(RomId & romId) |
IanBenzMaxim | 21:00c94aeb533e | 752 | { |
IanBenzMaxim | 21:00c94aeb533e | 753 | int id_bit_number; |
IanBenzMaxim | 21:00c94aeb533e | 754 | int last_zero, rom_byte_number; |
IanBenzMaxim | 21:00c94aeb533e | 755 | int id_bit, cmp_id_bit; |
IanBenzMaxim | 21:00c94aeb533e | 756 | unsigned char rom_byte_mask, status; |
IanBenzMaxim | 21:00c94aeb533e | 757 | bool search_result; |
IanBenzMaxim | 21:00c94aeb533e | 758 | unsigned char crc8 = 0; |
IanBenzMaxim | 21:00c94aeb533e | 759 | Direction search_direction; |
IanBenzMaxim | 21:00c94aeb533e | 760 | |
IanBenzMaxim | 21:00c94aeb533e | 761 | // initialize for search |
IanBenzMaxim | 21:00c94aeb533e | 762 | id_bit_number = 1; |
IanBenzMaxim | 21:00c94aeb533e | 763 | last_zero = 0; |
IanBenzMaxim | 21:00c94aeb533e | 764 | rom_byte_number = 0; |
IanBenzMaxim | 21:00c94aeb533e | 765 | rom_byte_mask = 1; |
IanBenzMaxim | 21:00c94aeb533e | 766 | search_result = false; |
IanBenzMaxim | 21:00c94aeb533e | 767 | |
IanBenzMaxim | 21:00c94aeb533e | 768 | // if the last call was not the last one |
IanBenzMaxim | 21:00c94aeb533e | 769 | if (!m_lastDeviceFlag) |
IanBenzMaxim | 21:00c94aeb533e | 770 | { |
IanBenzMaxim | 21:00c94aeb533e | 771 | // 1-Wire reset |
IanBenzMaxim | 21:00c94aeb533e | 772 | OneWireMaster::CmdResult result = OWReset(); |
IanBenzMaxim | 21:00c94aeb533e | 773 | if (result != OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 774 | { |
IanBenzMaxim | 21:00c94aeb533e | 775 | // reset the search |
IanBenzMaxim | 21:00c94aeb533e | 776 | m_lastDiscrepancy = 0; |
IanBenzMaxim | 21:00c94aeb533e | 777 | m_lastDeviceFlag = false; |
IanBenzMaxim | 21:00c94aeb533e | 778 | m_lastFamilyDiscrepancy = 0; |
IanBenzMaxim | 21:00c94aeb533e | 779 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 780 | } |
IanBenzMaxim | 21:00c94aeb533e | 781 | |
IanBenzMaxim | 21:00c94aeb533e | 782 | // issue the search command |
IanBenzMaxim | 21:00c94aeb533e | 783 | OWWriteByte(0xF0); |
IanBenzMaxim | 21:00c94aeb533e | 784 | |
IanBenzMaxim | 21:00c94aeb533e | 785 | // loop to do the search |
IanBenzMaxim | 21:00c94aeb533e | 786 | do |
IanBenzMaxim | 21:00c94aeb533e | 787 | { |
IanBenzMaxim | 21:00c94aeb533e | 788 | // if this discrepancy if before the Last Discrepancy |
IanBenzMaxim | 21:00c94aeb533e | 789 | // on a previous next then pick the same as last time |
IanBenzMaxim | 21:00c94aeb533e | 790 | if (id_bit_number < m_lastDiscrepancy) |
IanBenzMaxim | 21:00c94aeb533e | 791 | { |
IanBenzMaxim | 21:00c94aeb533e | 792 | if ((romId[rom_byte_number] & rom_byte_mask) > 0) |
IanBenzMaxim | 21:00c94aeb533e | 793 | search_direction = DIRECTION_WRITE_ONE; |
IanBenzMaxim | 21:00c94aeb533e | 794 | else |
IanBenzMaxim | 21:00c94aeb533e | 795 | search_direction = DIRECTION_WRITE_ZERO; |
IanBenzMaxim | 21:00c94aeb533e | 796 | } |
IanBenzMaxim | 21:00c94aeb533e | 797 | else |
IanBenzMaxim | 21:00c94aeb533e | 798 | { |
IanBenzMaxim | 21:00c94aeb533e | 799 | // if equal to last pick 1, if not then pick 0 |
IanBenzMaxim | 21:00c94aeb533e | 800 | if (id_bit_number == m_lastDiscrepancy) |
IanBenzMaxim | 21:00c94aeb533e | 801 | search_direction = DIRECTION_WRITE_ONE; |
IanBenzMaxim | 21:00c94aeb533e | 802 | else |
IanBenzMaxim | 21:00c94aeb533e | 803 | search_direction = DIRECTION_WRITE_ZERO; |
IanBenzMaxim | 21:00c94aeb533e | 804 | } |
IanBenzMaxim | 21:00c94aeb533e | 805 | |
IanBenzMaxim | 21:00c94aeb533e | 806 | // Peform a triple operation on the DS2465 which will perform 2 read bits and 1 write bit |
IanBenzMaxim | 21:00c94aeb533e | 807 | Triplet(search_direction, status); |
IanBenzMaxim | 21:00c94aeb533e | 808 | |
IanBenzMaxim | 21:00c94aeb533e | 809 | // check bit results in status byte |
IanBenzMaxim | 21:00c94aeb533e | 810 | id_bit = ((status & STATUS_SBR) == STATUS_SBR); |
IanBenzMaxim | 21:00c94aeb533e | 811 | cmp_id_bit = ((status & STATUS_TSB) == STATUS_TSB); |
IanBenzMaxim | 21:00c94aeb533e | 812 | search_direction = ((status & STATUS_DIR) == STATUS_DIR) ? DIRECTION_WRITE_ONE : DIRECTION_WRITE_ZERO; |
IanBenzMaxim | 21:00c94aeb533e | 813 | |
IanBenzMaxim | 21:00c94aeb533e | 814 | // check for no devices on 1-wire |
IanBenzMaxim | 21:00c94aeb533e | 815 | if ((id_bit) && (cmp_id_bit)) |
IanBenzMaxim | 21:00c94aeb533e | 816 | break; |
IanBenzMaxim | 21:00c94aeb533e | 817 | else |
IanBenzMaxim | 21:00c94aeb533e | 818 | { |
IanBenzMaxim | 21:00c94aeb533e | 819 | if ((!id_bit) && (!cmp_id_bit) && (search_direction == DIRECTION_WRITE_ZERO)) |
IanBenzMaxim | 21:00c94aeb533e | 820 | { |
IanBenzMaxim | 21:00c94aeb533e | 821 | last_zero = id_bit_number; |
IanBenzMaxim | 21:00c94aeb533e | 822 | |
IanBenzMaxim | 21:00c94aeb533e | 823 | // check for Last discrepancy in family |
IanBenzMaxim | 21:00c94aeb533e | 824 | if (last_zero < 9) |
IanBenzMaxim | 21:00c94aeb533e | 825 | m_lastFamilyDiscrepancy = last_zero; |
IanBenzMaxim | 21:00c94aeb533e | 826 | } |
IanBenzMaxim | 21:00c94aeb533e | 827 | |
IanBenzMaxim | 21:00c94aeb533e | 828 | // set or clear the bit in the ROM byte rom_byte_number |
IanBenzMaxim | 21:00c94aeb533e | 829 | // with mask rom_byte_mask |
IanBenzMaxim | 21:00c94aeb533e | 830 | if (search_direction == DIRECTION_WRITE_ONE) |
IanBenzMaxim | 21:00c94aeb533e | 831 | romId[rom_byte_number] |= rom_byte_mask; |
IanBenzMaxim | 21:00c94aeb533e | 832 | else |
IanBenzMaxim | 21:00c94aeb533e | 833 | romId[rom_byte_number] &= (unsigned char)~rom_byte_mask; |
IanBenzMaxim | 21:00c94aeb533e | 834 | |
IanBenzMaxim | 21:00c94aeb533e | 835 | // increment the byte counter id_bit_number |
IanBenzMaxim | 21:00c94aeb533e | 836 | // and shift the mask rom_byte_mask |
IanBenzMaxim | 21:00c94aeb533e | 837 | id_bit_number++; |
IanBenzMaxim | 21:00c94aeb533e | 838 | rom_byte_mask <<= 1; |
IanBenzMaxim | 21:00c94aeb533e | 839 | |
IanBenzMaxim | 21:00c94aeb533e | 840 | // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask |
IanBenzMaxim | 21:00c94aeb533e | 841 | if (rom_byte_mask == 0) |
IanBenzMaxim | 21:00c94aeb533e | 842 | { |
IanBenzMaxim | 21:00c94aeb533e | 843 | crc8 = RomId::calculateCRC8(crc8, romId[rom_byte_number]); // accumulate the CRC |
IanBenzMaxim | 21:00c94aeb533e | 844 | rom_byte_number++; |
IanBenzMaxim | 21:00c94aeb533e | 845 | rom_byte_mask = 1; |
IanBenzMaxim | 21:00c94aeb533e | 846 | } |
IanBenzMaxim | 21:00c94aeb533e | 847 | } |
IanBenzMaxim | 21:00c94aeb533e | 848 | } |
IanBenzMaxim | 21:00c94aeb533e | 849 | while(rom_byte_number < RomId::byteLen); // loop until through all ROM bytes 0-7 |
IanBenzMaxim | 21:00c94aeb533e | 850 | |
IanBenzMaxim | 21:00c94aeb533e | 851 | // if the search was successful then |
IanBenzMaxim | 21:00c94aeb533e | 852 | if (!((id_bit_number <= (RomId::byteLen * 8)) || (crc8 != 0))) |
IanBenzMaxim | 21:00c94aeb533e | 853 | { |
IanBenzMaxim | 21:00c94aeb533e | 854 | // search successful so set m_lastDiscrepancy,m_lastDeviceFlag,search_result |
IanBenzMaxim | 21:00c94aeb533e | 855 | m_lastDiscrepancy = last_zero; |
IanBenzMaxim | 21:00c94aeb533e | 856 | |
IanBenzMaxim | 21:00c94aeb533e | 857 | // check for last device |
IanBenzMaxim | 21:00c94aeb533e | 858 | if (m_lastDiscrepancy == 0) |
IanBenzMaxim | 21:00c94aeb533e | 859 | m_lastDeviceFlag = true; |
IanBenzMaxim | 21:00c94aeb533e | 860 | |
IanBenzMaxim | 21:00c94aeb533e | 861 | search_result = true; |
IanBenzMaxim | 21:00c94aeb533e | 862 | } |
IanBenzMaxim | 21:00c94aeb533e | 863 | } |
IanBenzMaxim | 21:00c94aeb533e | 864 | |
IanBenzMaxim | 21:00c94aeb533e | 865 | // if no device found then reset counters so next 'search' will be like a first |
IanBenzMaxim | 21:00c94aeb533e | 866 | if (!search_result || (romId.familyCode() == 0)) |
IanBenzMaxim | 21:00c94aeb533e | 867 | { |
IanBenzMaxim | 21:00c94aeb533e | 868 | m_lastDiscrepancy = 0; |
IanBenzMaxim | 21:00c94aeb533e | 869 | m_lastDeviceFlag = false; |
IanBenzMaxim | 21:00c94aeb533e | 870 | m_lastFamilyDiscrepancy = 0; |
IanBenzMaxim | 21:00c94aeb533e | 871 | search_result = false; |
IanBenzMaxim | 21:00c94aeb533e | 872 | } |
IanBenzMaxim | 21:00c94aeb533e | 873 | |
IanBenzMaxim | 21:00c94aeb533e | 874 | return search_result ? OneWireMaster::Success : OneWireMaster::OperationFailure; |
IanBenzMaxim | 21:00c94aeb533e | 875 | } |
IanBenzMaxim | 21:00c94aeb533e | 876 | |
IanBenzMaxim | 21:00c94aeb533e | 877 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 878 | // Find the 'first' devices on the 1-Wire network |
IanBenzMaxim | 21:00c94aeb533e | 879 | // Return true : device found, ROM number in ROM_NO buffer |
IanBenzMaxim | 21:00c94aeb533e | 880 | // false : no device present |
IanBenzMaxim | 21:00c94aeb533e | 881 | // |
IanBenzMaxim | 21:00c94aeb533e | 882 | OneWireMaster::CmdResult DS2465::OWFirst(RomId & romId) |
IanBenzMaxim | 21:00c94aeb533e | 883 | { |
IanBenzMaxim | 21:00c94aeb533e | 884 | // reset the search state |
IanBenzMaxim | 21:00c94aeb533e | 885 | m_lastDiscrepancy = 0; |
IanBenzMaxim | 21:00c94aeb533e | 886 | m_lastDeviceFlag = false; |
IanBenzMaxim | 21:00c94aeb533e | 887 | m_lastFamilyDiscrepancy = 0; |
IanBenzMaxim | 21:00c94aeb533e | 888 | |
IanBenzMaxim | 21:00c94aeb533e | 889 | return OWSearch(romId); |
IanBenzMaxim | 21:00c94aeb533e | 890 | } |
IanBenzMaxim | 21:00c94aeb533e | 891 | |
IanBenzMaxim | 21:00c94aeb533e | 892 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 893 | // The 'OWReadBlock' receives a block of data from the |
IanBenzMaxim | 21:00c94aeb533e | 894 | // 1-Wire Net. The destination is the mac buffer (rx_mac=1) or |
IanBenzMaxim | 21:00c94aeb533e | 895 | // the scratchpad (rx_mac=0). The result is buffer is returned. |
IanBenzMaxim | 21:00c94aeb533e | 896 | // |
IanBenzMaxim | 21:00c94aeb533e | 897 | // 'rx_buf' - pointer to a block to receive bytes |
IanBenzMaxim | 21:00c94aeb533e | 898 | // of length 'rx_len' from 1-Wire Net |
IanBenzMaxim | 21:00c94aeb533e | 899 | // 'rx_len' - length in bytes to read. Only valid numbers are 8,16,20,32; |
IanBenzMaxim | 21:00c94aeb533e | 900 | // |
IanBenzMaxim | 21:00c94aeb533e | 901 | OneWireMaster::CmdResult DS2465::OWReadBlock(uint8_t *rx_buf, uint8_t rx_len) |
IanBenzMaxim | 21:00c94aeb533e | 902 | { |
IanBenzMaxim | 21:00c94aeb533e | 903 | uint8_t status; |
IanBenzMaxim | 21:00c94aeb533e | 904 | int poll_count = 0; |
IanBenzMaxim | 21:00c94aeb533e | 905 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 21:00c94aeb533e | 906 | |
IanBenzMaxim | 21:00c94aeb533e | 907 | // 1-Wire Receive Block (Case A) |
IanBenzMaxim | 21:00c94aeb533e | 908 | // S AD,0 [A] ADDR_CMD_REG [A] 1WRF [A] PR [A] P |
IanBenzMaxim | 21:00c94aeb533e | 909 | // [] indicates from slave |
IanBenzMaxim | 21:00c94aeb533e | 910 | // PR indicates byte containing parameter |
IanBenzMaxim | 21:00c94aeb533e | 911 | |
IanBenzMaxim | 21:00c94aeb533e | 912 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 913 | if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 914 | { |
IanBenzMaxim | 21:00c94aeb533e | 915 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 916 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 917 | } |
IanBenzMaxim | 21:00c94aeb533e | 918 | if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 919 | { |
IanBenzMaxim | 21:00c94aeb533e | 920 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 921 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 922 | } |
IanBenzMaxim | 21:00c94aeb533e | 923 | if (m_I2C_interface.write(CMD_1WRF) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 924 | { |
IanBenzMaxim | 21:00c94aeb533e | 925 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 926 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 927 | } |
IanBenzMaxim | 21:00c94aeb533e | 928 | if (m_I2C_interface.write((unsigned char)rx_len) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 929 | { |
IanBenzMaxim | 21:00c94aeb533e | 930 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 931 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 932 | } |
IanBenzMaxim | 21:00c94aeb533e | 933 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 934 | status = STATUS_1WB; |
IanBenzMaxim | 21:00c94aeb533e | 935 | |
IanBenzMaxim | 21:00c94aeb533e | 936 | // loop checking 1WB bit for completion of 1-Wire operation |
IanBenzMaxim | 21:00c94aeb533e | 937 | // abort if poll limit reached |
IanBenzMaxim | 21:00c94aeb533e | 938 | while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT)) |
IanBenzMaxim | 21:00c94aeb533e | 939 | { |
IanBenzMaxim | 21:00c94aeb533e | 940 | result = ReadMemory(ADDR_STATUS_REG, &status, 1, false); |
IanBenzMaxim | 21:00c94aeb533e | 941 | if (result != OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 942 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 943 | } |
IanBenzMaxim | 21:00c94aeb533e | 944 | |
IanBenzMaxim | 21:00c94aeb533e | 945 | // check for failure due to poll limit reached |
IanBenzMaxim | 21:00c94aeb533e | 946 | if (poll_count >= POLL_LIMIT) |
IanBenzMaxim | 21:00c94aeb533e | 947 | { |
IanBenzMaxim | 21:00c94aeb533e | 948 | // handle error |
IanBenzMaxim | 21:00c94aeb533e | 949 | // ... |
IanBenzMaxim | 21:00c94aeb533e | 950 | //Reset(); |
IanBenzMaxim | 21:00c94aeb533e | 951 | return OneWireMaster::TimeoutError; |
IanBenzMaxim | 21:00c94aeb533e | 952 | } |
IanBenzMaxim | 21:00c94aeb533e | 953 | |
IanBenzMaxim | 21:00c94aeb533e | 954 | result = ReadMemory(ADDR_SPAD, rx_buf, rx_len, false); |
IanBenzMaxim | 21:00c94aeb533e | 955 | |
IanBenzMaxim | 21:00c94aeb533e | 956 | // read out the data |
IanBenzMaxim | 21:00c94aeb533e | 957 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 958 | } |
IanBenzMaxim | 21:00c94aeb533e | 959 | |
IanBenzMaxim | 21:00c94aeb533e | 960 | |
IanBenzMaxim | 21:00c94aeb533e | 961 | |
IanBenzMaxim | 21:00c94aeb533e | 962 | |
IanBenzMaxim | 21:00c94aeb533e | 963 | OneWireMaster::CmdResult DS2465::OWWriteBlock(const uint8_t *tran_buf, uint8_t tran_len) |
IanBenzMaxim | 21:00c94aeb533e | 964 | { |
IanBenzMaxim | 21:00c94aeb533e | 965 | return OWWriteBlock(false, tran_buf, tran_len); |
IanBenzMaxim | 21:00c94aeb533e | 966 | } |
IanBenzMaxim | 21:00c94aeb533e | 967 | |
IanBenzMaxim | 21:00c94aeb533e | 968 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 969 | // The 'OWWriteBlock' transfers a block of data to the |
IanBenzMaxim | 21:00c94aeb533e | 970 | // 1-Wire Net. The mac buffer can be sent (tx_mac=1) or a |
IanBenzMaxim | 21:00c94aeb533e | 971 | // portion of the scratchpad can be sent. |
IanBenzMaxim | 21:00c94aeb533e | 972 | // |
IanBenzMaxim | 21:00c94aeb533e | 973 | // 'tx_mac' - flag to indicate if the MAC buffer is to be sent (1) or |
IanBenzMaxim | 21:00c94aeb533e | 974 | // the data provided in teh tran_buf is to be sent (0) |
IanBenzMaxim | 21:00c94aeb533e | 975 | // 'tran_buf' - pointer to a block of bytes |
IanBenzMaxim | 21:00c94aeb533e | 976 | // of length 'tran_len' that will be sent |
IanBenzMaxim | 21:00c94aeb533e | 977 | // to the 1-Wire Net |
IanBenzMaxim | 21:00c94aeb533e | 978 | // 'tran_len' - length in bytes to transfer. Only valid numbers are 8,16,20,32; |
IanBenzMaxim | 21:00c94aeb533e | 979 | // |
IanBenzMaxim | 21:00c94aeb533e | 980 | OneWireMaster::CmdResult DS2465::OWWriteBlock(bool tx_mac, const uint8_t *tran_buf, uint8_t tran_len) |
IanBenzMaxim | 21:00c94aeb533e | 981 | { |
IanBenzMaxim | 21:00c94aeb533e | 982 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 21:00c94aeb533e | 983 | uint8_t par, status; |
IanBenzMaxim | 21:00c94aeb533e | 984 | int poll_count = 0; |
IanBenzMaxim | 21:00c94aeb533e | 985 | |
IanBenzMaxim | 21:00c94aeb533e | 986 | // create parameter byte |
IanBenzMaxim | 21:00c94aeb533e | 987 | if (tx_mac) |
IanBenzMaxim | 21:00c94aeb533e | 988 | par = 0xFF; |
IanBenzMaxim | 21:00c94aeb533e | 989 | else |
IanBenzMaxim | 21:00c94aeb533e | 990 | { |
IanBenzMaxim | 21:00c94aeb533e | 991 | // scratchpad is source |
IanBenzMaxim | 21:00c94aeb533e | 992 | par = tran_len; |
IanBenzMaxim | 21:00c94aeb533e | 993 | |
IanBenzMaxim | 21:00c94aeb533e | 994 | // prefill scratchpad with required data |
IanBenzMaxim | 21:00c94aeb533e | 995 | result = WriteScratchpad(ADDR_SPAD, tran_buf, tran_len); |
IanBenzMaxim | 21:00c94aeb533e | 996 | if (result != OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 997 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 998 | } |
IanBenzMaxim | 21:00c94aeb533e | 999 | |
IanBenzMaxim | 21:00c94aeb533e | 1000 | // 1-Wire Transmit Block (Case A) |
IanBenzMaxim | 21:00c94aeb533e | 1001 | // S AD,0 [A] ADDR_CMD_REG [A] 1WTB [A] PR [A] P |
IanBenzMaxim | 21:00c94aeb533e | 1002 | // [] indicates from slave |
IanBenzMaxim | 21:00c94aeb533e | 1003 | // PR indicates byte containing parameter |
IanBenzMaxim | 21:00c94aeb533e | 1004 | |
IanBenzMaxim | 21:00c94aeb533e | 1005 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 1006 | if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1007 | { |
IanBenzMaxim | 21:00c94aeb533e | 1008 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1009 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1010 | } |
IanBenzMaxim | 21:00c94aeb533e | 1011 | if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1012 | { |
IanBenzMaxim | 21:00c94aeb533e | 1013 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1014 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1015 | } |
IanBenzMaxim | 21:00c94aeb533e | 1016 | if (m_I2C_interface.write(CMD_1WTB) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1017 | { |
IanBenzMaxim | 21:00c94aeb533e | 1018 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1019 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1020 | } |
IanBenzMaxim | 21:00c94aeb533e | 1021 | if (m_I2C_interface.write(par) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1022 | { |
IanBenzMaxim | 21:00c94aeb533e | 1023 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1024 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1025 | } |
IanBenzMaxim | 21:00c94aeb533e | 1026 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1027 | |
IanBenzMaxim | 21:00c94aeb533e | 1028 | // loop checking 1WB bit for completion of 1-Wire operation |
IanBenzMaxim | 21:00c94aeb533e | 1029 | // abort if poll limit reached |
IanBenzMaxim | 21:00c94aeb533e | 1030 | status = STATUS_1WB; |
IanBenzMaxim | 21:00c94aeb533e | 1031 | while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT)) |
IanBenzMaxim | 21:00c94aeb533e | 1032 | { |
IanBenzMaxim | 21:00c94aeb533e | 1033 | result = ReadMemory(ADDR_STATUS_REG, &status, 1, false); |
IanBenzMaxim | 21:00c94aeb533e | 1034 | if (result != OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 1035 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 1036 | } |
IanBenzMaxim | 21:00c94aeb533e | 1037 | |
IanBenzMaxim | 21:00c94aeb533e | 1038 | // check for failure due to poll limit reached |
IanBenzMaxim | 21:00c94aeb533e | 1039 | if (poll_count >= POLL_LIMIT) |
IanBenzMaxim | 21:00c94aeb533e | 1040 | { |
IanBenzMaxim | 21:00c94aeb533e | 1041 | // handle error |
IanBenzMaxim | 21:00c94aeb533e | 1042 | // ... |
IanBenzMaxim | 21:00c94aeb533e | 1043 | //Reset(); |
IanBenzMaxim | 21:00c94aeb533e | 1044 | return OneWireMaster::TimeoutError; |
IanBenzMaxim | 21:00c94aeb533e | 1045 | } |
IanBenzMaxim | 21:00c94aeb533e | 1046 | |
IanBenzMaxim | 21:00c94aeb533e | 1047 | return OneWireMaster::Success; |
IanBenzMaxim | 21:00c94aeb533e | 1048 | } |
IanBenzMaxim | 21:00c94aeb533e | 1049 | |
IanBenzMaxim | 21:00c94aeb533e | 1050 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 1051 | // The 'OWBlock' transfers a block of data to and from the |
IanBenzMaxim | 21:00c94aeb533e | 1052 | // 1-Wire Net. The result is returned in the same buffer. |
IanBenzMaxim | 21:00c94aeb533e | 1053 | // |
IanBenzMaxim | 21:00c94aeb533e | 1054 | // 'tran_buf' - pointer to a block of unsigned |
IanBenzMaxim | 21:00c94aeb533e | 1055 | // chars of length 'tran_len' that will be sent |
IanBenzMaxim | 21:00c94aeb533e | 1056 | // to the 1-Wire Net |
IanBenzMaxim | 21:00c94aeb533e | 1057 | // 'tran_len' - length in bytes to transfer |
IanBenzMaxim | 21:00c94aeb533e | 1058 | // |
IanBenzMaxim | 21:00c94aeb533e | 1059 | OneWireMaster::CmdResult DS2465::OWBlock(uint8_t *tran_buf, uint8_t tran_len) |
IanBenzMaxim | 21:00c94aeb533e | 1060 | { |
IanBenzMaxim | 21:00c94aeb533e | 1061 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 21:00c94aeb533e | 1062 | for (uint8_t i = 0; i < tran_len; i++) |
IanBenzMaxim | 21:00c94aeb533e | 1063 | { |
IanBenzMaxim | 21:00c94aeb533e | 1064 | result = OWTouchByte(tran_buf[i]); |
IanBenzMaxim | 21:00c94aeb533e | 1065 | if (result != OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 1066 | break; |
IanBenzMaxim | 21:00c94aeb533e | 1067 | } |
IanBenzMaxim | 21:00c94aeb533e | 1068 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 1069 | } |
IanBenzMaxim | 21:00c94aeb533e | 1070 | |
IanBenzMaxim | 21:00c94aeb533e | 1071 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 1072 | // Send 8 bits of communication to the 1-Wire Net and return the |
IanBenzMaxim | 21:00c94aeb533e | 1073 | // result 8 bits read from the 1-Wire Net. The parameter 'sendbyte' |
IanBenzMaxim | 21:00c94aeb533e | 1074 | // least significant 8 bits are used and the least significant 8 bits |
IanBenzMaxim | 21:00c94aeb533e | 1075 | // of the result is the return byte. |
IanBenzMaxim | 21:00c94aeb533e | 1076 | // |
IanBenzMaxim | 21:00c94aeb533e | 1077 | // 'sendbyte' - 8 bits to send (least significant byte) |
IanBenzMaxim | 21:00c94aeb533e | 1078 | // |
IanBenzMaxim | 21:00c94aeb533e | 1079 | // Returns: 8 bits read from sendbyte |
IanBenzMaxim | 21:00c94aeb533e | 1080 | // |
IanBenzMaxim | 21:00c94aeb533e | 1081 | OneWireMaster::CmdResult DS2465::OWTouchByte(uint8_t & sendrecvbyte) |
IanBenzMaxim | 21:00c94aeb533e | 1082 | { |
IanBenzMaxim | 21:00c94aeb533e | 1083 | OneWireMaster::CmdResult result = OWWriteByte(sendrecvbyte); |
IanBenzMaxim | 21:00c94aeb533e | 1084 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 1085 | OWReadByte(sendrecvbyte); |
IanBenzMaxim | 21:00c94aeb533e | 1086 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 1087 | } |
IanBenzMaxim | 21:00c94aeb533e | 1088 | |
IanBenzMaxim | 21:00c94aeb533e | 1089 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 1090 | // Send 8 bits of read communication to the 1-Wire Net and return the |
IanBenzMaxim | 21:00c94aeb533e | 1091 | // result 8 bits read from the 1-Wire Net. |
IanBenzMaxim | 21:00c94aeb533e | 1092 | // |
IanBenzMaxim | 21:00c94aeb533e | 1093 | // Returns: 8 bits read from 1-Wire Net |
IanBenzMaxim | 21:00c94aeb533e | 1094 | // |
IanBenzMaxim | 21:00c94aeb533e | 1095 | OneWireMaster::CmdResult DS2465::OWReadByte(uint8_t & recvbyte) |
IanBenzMaxim | 21:00c94aeb533e | 1096 | { |
IanBenzMaxim | 21:00c94aeb533e | 1097 | uint8_t status; |
IanBenzMaxim | 21:00c94aeb533e | 1098 | int poll_count = 0; |
IanBenzMaxim | 21:00c94aeb533e | 1099 | |
IanBenzMaxim | 21:00c94aeb533e | 1100 | // 1-Wire Read Bytes (Case C) |
j3 | 22:686273e55cdc | 1101 | // S AD,0 [A] ADDR_CMD_REG [A] 1WRB [A] Sr AD,1 [A] [Status] A [Status] A |
IanBenzMaxim | 21:00c94aeb533e | 1102 | // \--------/ |
IanBenzMaxim | 21:00c94aeb533e | 1103 | // Repeat until 1WB bit has changed to 0 |
IanBenzMaxim | 21:00c94aeb533e | 1104 | // Sr AD,0 [A] SRP [A] E1 [A] Sr AD,1 [A] DD A\ P |
IanBenzMaxim | 21:00c94aeb533e | 1105 | // |
IanBenzMaxim | 21:00c94aeb533e | 1106 | // [] indicates from slave |
IanBenzMaxim | 21:00c94aeb533e | 1107 | // DD data read |
IanBenzMaxim | 21:00c94aeb533e | 1108 | |
IanBenzMaxim | 21:00c94aeb533e | 1109 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 1110 | if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1111 | { |
IanBenzMaxim | 21:00c94aeb533e | 1112 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1113 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1114 | } |
IanBenzMaxim | 21:00c94aeb533e | 1115 | if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1116 | { |
IanBenzMaxim | 21:00c94aeb533e | 1117 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1118 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1119 | } |
IanBenzMaxim | 21:00c94aeb533e | 1120 | if (m_I2C_interface.write(CMD_1WRB) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1121 | { |
IanBenzMaxim | 21:00c94aeb533e | 1122 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1123 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1124 | } |
IanBenzMaxim | 21:00c94aeb533e | 1125 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 1126 | if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_READ)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1127 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1128 | |
IanBenzMaxim | 21:00c94aeb533e | 1129 | // loop checking 1WB bit for completion of 1-Wire operation |
IanBenzMaxim | 21:00c94aeb533e | 1130 | // abort if poll limit reached |
IanBenzMaxim | 21:00c94aeb533e | 1131 | status = STATUS_1WB; |
IanBenzMaxim | 21:00c94aeb533e | 1132 | while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT)) |
IanBenzMaxim | 21:00c94aeb533e | 1133 | { |
IanBenzMaxim | 21:00c94aeb533e | 1134 | status = m_I2C_interface.read(m_I2C_interface.ACK); |
IanBenzMaxim | 21:00c94aeb533e | 1135 | } |
IanBenzMaxim | 21:00c94aeb533e | 1136 | |
IanBenzMaxim | 21:00c94aeb533e | 1137 | // one last read with NACK |
IanBenzMaxim | 21:00c94aeb533e | 1138 | m_I2C_interface.read(m_I2C_interface.NoACK); |
IanBenzMaxim | 21:00c94aeb533e | 1139 | |
IanBenzMaxim | 21:00c94aeb533e | 1140 | // check for failure due to poll limit reached |
IanBenzMaxim | 21:00c94aeb533e | 1141 | if (poll_count >= POLL_LIMIT) |
IanBenzMaxim | 21:00c94aeb533e | 1142 | { |
IanBenzMaxim | 21:00c94aeb533e | 1143 | // handle error |
IanBenzMaxim | 21:00c94aeb533e | 1144 | // ... |
IanBenzMaxim | 21:00c94aeb533e | 1145 | //Reset(); |
IanBenzMaxim | 21:00c94aeb533e | 1146 | return OneWireMaster::TimeoutError; |
IanBenzMaxim | 21:00c94aeb533e | 1147 | } |
IanBenzMaxim | 21:00c94aeb533e | 1148 | |
IanBenzMaxim | 21:00c94aeb533e | 1149 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 1150 | if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1151 | { |
IanBenzMaxim | 21:00c94aeb533e | 1152 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1153 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1154 | } |
IanBenzMaxim | 21:00c94aeb533e | 1155 | if (m_I2C_interface.write(ADDR_DATA_REG) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1156 | { |
IanBenzMaxim | 21:00c94aeb533e | 1157 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1158 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1159 | } |
IanBenzMaxim | 21:00c94aeb533e | 1160 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 1161 | if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_READ)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1162 | { |
IanBenzMaxim | 21:00c94aeb533e | 1163 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1164 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1165 | } |
IanBenzMaxim | 21:00c94aeb533e | 1166 | recvbyte = m_I2C_interface.read(m_I2C_interface.NoACK); |
IanBenzMaxim | 21:00c94aeb533e | 1167 | |
IanBenzMaxim | 21:00c94aeb533e | 1168 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1169 | |
IanBenzMaxim | 21:00c94aeb533e | 1170 | return OneWireMaster::Success; |
IanBenzMaxim | 21:00c94aeb533e | 1171 | } |
IanBenzMaxim | 21:00c94aeb533e | 1172 | |
IanBenzMaxim | 21:00c94aeb533e | 1173 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 1174 | // Send 8 bits of communication to the 1-Wire Net and verify that the |
IanBenzMaxim | 21:00c94aeb533e | 1175 | // 8 bits read from the 1-Wire Net is the same (write operation). |
IanBenzMaxim | 21:00c94aeb533e | 1176 | // The parameter 'sendbyte' least significant 8 bits are used. |
IanBenzMaxim | 21:00c94aeb533e | 1177 | // |
IanBenzMaxim | 21:00c94aeb533e | 1178 | // 'sendbyte' - 8 bits to send (least significant byte) |
IanBenzMaxim | 21:00c94aeb533e | 1179 | // |
IanBenzMaxim | 21:00c94aeb533e | 1180 | // Returns: true: bytes written and echo was the same |
IanBenzMaxim | 21:00c94aeb533e | 1181 | // false: echo was not the same |
IanBenzMaxim | 21:00c94aeb533e | 1182 | // |
IanBenzMaxim | 21:00c94aeb533e | 1183 | OneWireMaster::CmdResult DS2465::OWWriteByte(uint8_t sendbyte) |
IanBenzMaxim | 21:00c94aeb533e | 1184 | { |
IanBenzMaxim | 21:00c94aeb533e | 1185 | uint8_t status; |
IanBenzMaxim | 21:00c94aeb533e | 1186 | int poll_count = 0; |
IanBenzMaxim | 21:00c94aeb533e | 1187 | |
IanBenzMaxim | 21:00c94aeb533e | 1188 | // 1-Wire Write Byte (Case B) |
IanBenzMaxim | 21:00c94aeb533e | 1189 | // S AD,0 [A] ADDR_CMD_REG [A] 1WWB [A] DD [A] Sr AD,1 [A] [Status] A [Status] A\ P |
IanBenzMaxim | 21:00c94aeb533e | 1190 | // \--------/ |
IanBenzMaxim | 21:00c94aeb533e | 1191 | // Repeat until 1WB bit has changed to 0 |
IanBenzMaxim | 21:00c94aeb533e | 1192 | // [] indicates from slave |
IanBenzMaxim | 21:00c94aeb533e | 1193 | // DD data to write |
IanBenzMaxim | 21:00c94aeb533e | 1194 | |
IanBenzMaxim | 21:00c94aeb533e | 1195 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 1196 | if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1197 | { |
IanBenzMaxim | 21:00c94aeb533e | 1198 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1199 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1200 | } |
IanBenzMaxim | 21:00c94aeb533e | 1201 | if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1202 | { |
IanBenzMaxim | 21:00c94aeb533e | 1203 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1204 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1205 | } |
IanBenzMaxim | 21:00c94aeb533e | 1206 | if (m_I2C_interface.write(CMD_1WWB) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1207 | { |
IanBenzMaxim | 21:00c94aeb533e | 1208 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1209 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1210 | } |
IanBenzMaxim | 21:00c94aeb533e | 1211 | if (m_I2C_interface.write(sendbyte) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1212 | { |
IanBenzMaxim | 21:00c94aeb533e | 1213 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1214 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1215 | } |
IanBenzMaxim | 21:00c94aeb533e | 1216 | |
IanBenzMaxim | 21:00c94aeb533e | 1217 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 1218 | if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_READ)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1219 | { |
IanBenzMaxim | 21:00c94aeb533e | 1220 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1221 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1222 | } |
IanBenzMaxim | 21:00c94aeb533e | 1223 | |
IanBenzMaxim | 21:00c94aeb533e | 1224 | // loop checking 1WB bit for completion of 1-Wire operation |
IanBenzMaxim | 21:00c94aeb533e | 1225 | // abort if poll limit reached |
IanBenzMaxim | 21:00c94aeb533e | 1226 | status = STATUS_1WB; |
IanBenzMaxim | 21:00c94aeb533e | 1227 | while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT)) |
IanBenzMaxim | 21:00c94aeb533e | 1228 | { |
IanBenzMaxim | 21:00c94aeb533e | 1229 | status = m_I2C_interface.read(m_I2C_interface.ACK); |
IanBenzMaxim | 21:00c94aeb533e | 1230 | } |
IanBenzMaxim | 21:00c94aeb533e | 1231 | |
IanBenzMaxim | 21:00c94aeb533e | 1232 | // one last read with NACK |
IanBenzMaxim | 21:00c94aeb533e | 1233 | m_I2C_interface.read(m_I2C_interface.NoACK); |
IanBenzMaxim | 21:00c94aeb533e | 1234 | |
IanBenzMaxim | 21:00c94aeb533e | 1235 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1236 | |
IanBenzMaxim | 21:00c94aeb533e | 1237 | // check for failure due to poll limit reached |
IanBenzMaxim | 21:00c94aeb533e | 1238 | if (poll_count >= POLL_LIMIT) |
IanBenzMaxim | 21:00c94aeb533e | 1239 | { |
IanBenzMaxim | 21:00c94aeb533e | 1240 | // handle error |
IanBenzMaxim | 21:00c94aeb533e | 1241 | // ... |
IanBenzMaxim | 21:00c94aeb533e | 1242 | //Reset(); |
IanBenzMaxim | 21:00c94aeb533e | 1243 | return OneWireMaster::TimeoutError; |
IanBenzMaxim | 21:00c94aeb533e | 1244 | } |
IanBenzMaxim | 21:00c94aeb533e | 1245 | |
IanBenzMaxim | 21:00c94aeb533e | 1246 | return OneWireMaster::Success; |
IanBenzMaxim | 21:00c94aeb533e | 1247 | } |
IanBenzMaxim | 21:00c94aeb533e | 1248 | |
IanBenzMaxim | 21:00c94aeb533e | 1249 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 1250 | // Send 1 bit of communication to the 1-Wire Net and return the |
IanBenzMaxim | 21:00c94aeb533e | 1251 | // result 1 bit read from the 1-Wire Net. The parameter 'sendbit' |
IanBenzMaxim | 21:00c94aeb533e | 1252 | // least significant bit is used and the least significant bit |
IanBenzMaxim | 21:00c94aeb533e | 1253 | // of the result is the return bit. |
IanBenzMaxim | 21:00c94aeb533e | 1254 | // |
IanBenzMaxim | 21:00c94aeb533e | 1255 | // 'sendbit' - the least significant bit is the bit to send |
IanBenzMaxim | 21:00c94aeb533e | 1256 | // |
IanBenzMaxim | 21:00c94aeb533e | 1257 | // Returns: 0: 0 bit read from sendbit |
IanBenzMaxim | 21:00c94aeb533e | 1258 | // 1: 1 bit read from sendbit |
IanBenzMaxim | 21:00c94aeb533e | 1259 | // |
IanBenzMaxim | 21:00c94aeb533e | 1260 | OneWireMaster::CmdResult DS2465::OWTouchBit(uint8_t & sendrecvbit) |
IanBenzMaxim | 21:00c94aeb533e | 1261 | { |
IanBenzMaxim | 21:00c94aeb533e | 1262 | unsigned char status; |
IanBenzMaxim | 21:00c94aeb533e | 1263 | int poll_count = 0; |
IanBenzMaxim | 21:00c94aeb533e | 1264 | |
IanBenzMaxim | 21:00c94aeb533e | 1265 | // 1-Wire bit (Case B) |
IanBenzMaxim | 21:00c94aeb533e | 1266 | // S AD,0 [A] ADDR_CMD_REG [A] 1WSB [A] BB [A] Sr AD,1 [A] [Status] A [Status] A\ P |
IanBenzMaxim | 21:00c94aeb533e | 1267 | // \--------/ |
IanBenzMaxim | 21:00c94aeb533e | 1268 | // Repeat until 1WB bit has changed to 0 |
IanBenzMaxim | 21:00c94aeb533e | 1269 | // [] indicates from slave |
IanBenzMaxim | 21:00c94aeb533e | 1270 | // BB indicates byte containing bit value in msbit |
IanBenzMaxim | 21:00c94aeb533e | 1271 | |
IanBenzMaxim | 21:00c94aeb533e | 1272 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 1273 | if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1274 | { |
IanBenzMaxim | 21:00c94aeb533e | 1275 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1276 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1277 | } |
IanBenzMaxim | 21:00c94aeb533e | 1278 | if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1279 | { |
IanBenzMaxim | 21:00c94aeb533e | 1280 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1281 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1282 | } |
IanBenzMaxim | 21:00c94aeb533e | 1283 | if (m_I2C_interface.write(CMD_1WSB) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1284 | { |
IanBenzMaxim | 21:00c94aeb533e | 1285 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1286 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1287 | } |
IanBenzMaxim | 21:00c94aeb533e | 1288 | if (m_I2C_interface.write(sendrecvbit ? 0x80 : 0x00) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1289 | { |
IanBenzMaxim | 21:00c94aeb533e | 1290 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1291 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1292 | } |
IanBenzMaxim | 21:00c94aeb533e | 1293 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 1294 | if (m_I2C_interface.write(m_I2C_address | I2C_READ) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1295 | { |
IanBenzMaxim | 21:00c94aeb533e | 1296 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1297 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1298 | } |
IanBenzMaxim | 21:00c94aeb533e | 1299 | |
IanBenzMaxim | 21:00c94aeb533e | 1300 | // loop checking 1WB bit for completion of 1-Wire operation |
IanBenzMaxim | 21:00c94aeb533e | 1301 | // abort if poll limit reached |
IanBenzMaxim | 21:00c94aeb533e | 1302 | status = STATUS_1WB; |
IanBenzMaxim | 21:00c94aeb533e | 1303 | while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT)) |
IanBenzMaxim | 21:00c94aeb533e | 1304 | { |
IanBenzMaxim | 21:00c94aeb533e | 1305 | status = m_I2C_interface.read(status & STATUS_1WB); |
IanBenzMaxim | 21:00c94aeb533e | 1306 | } |
IanBenzMaxim | 21:00c94aeb533e | 1307 | |
IanBenzMaxim | 21:00c94aeb533e | 1308 | // one last read with NACK |
IanBenzMaxim | 21:00c94aeb533e | 1309 | m_I2C_interface.read(m_I2C_interface.NoACK); |
IanBenzMaxim | 21:00c94aeb533e | 1310 | |
IanBenzMaxim | 21:00c94aeb533e | 1311 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1312 | |
IanBenzMaxim | 21:00c94aeb533e | 1313 | // check for failure due to poll limit reached |
IanBenzMaxim | 21:00c94aeb533e | 1314 | if (poll_count >= POLL_LIMIT) |
IanBenzMaxim | 21:00c94aeb533e | 1315 | { |
IanBenzMaxim | 21:00c94aeb533e | 1316 | // handle error |
IanBenzMaxim | 21:00c94aeb533e | 1317 | // ... |
IanBenzMaxim | 21:00c94aeb533e | 1318 | //Reset(); |
IanBenzMaxim | 21:00c94aeb533e | 1319 | return OneWireMaster::TimeoutError; |
IanBenzMaxim | 21:00c94aeb533e | 1320 | } |
IanBenzMaxim | 21:00c94aeb533e | 1321 | |
IanBenzMaxim | 21:00c94aeb533e | 1322 | // check bit state |
IanBenzMaxim | 21:00c94aeb533e | 1323 | sendrecvbit = (status & STATUS_SBR); |
IanBenzMaxim | 21:00c94aeb533e | 1324 | |
IanBenzMaxim | 21:00c94aeb533e | 1325 | return OneWireMaster::Success; |
IanBenzMaxim | 21:00c94aeb533e | 1326 | } |
IanBenzMaxim | 21:00c94aeb533e | 1327 | |
IanBenzMaxim | 21:00c94aeb533e | 1328 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 1329 | // Reads 1 bit of communication from the 1-Wire Net and returns the |
IanBenzMaxim | 21:00c94aeb533e | 1330 | // result |
IanBenzMaxim | 21:00c94aeb533e | 1331 | // |
IanBenzMaxim | 21:00c94aeb533e | 1332 | // Returns: 1 bit read from 1-Wire Net |
IanBenzMaxim | 21:00c94aeb533e | 1333 | // |
IanBenzMaxim | 21:00c94aeb533e | 1334 | OneWireMaster::CmdResult DS2465::OWReadBit(uint8_t & recvbit) |
IanBenzMaxim | 21:00c94aeb533e | 1335 | { |
IanBenzMaxim | 21:00c94aeb533e | 1336 | recvbit = 0x01; |
IanBenzMaxim | 21:00c94aeb533e | 1337 | return OWTouchBit(recvbit); |
IanBenzMaxim | 21:00c94aeb533e | 1338 | } |
IanBenzMaxim | 21:00c94aeb533e | 1339 | |
IanBenzMaxim | 21:00c94aeb533e | 1340 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 1341 | // Send 1 bit of communication to the 1-Wire Net. |
IanBenzMaxim | 21:00c94aeb533e | 1342 | // The parameter 'sendbit' least significant bit is used. |
IanBenzMaxim | 21:00c94aeb533e | 1343 | // |
IanBenzMaxim | 21:00c94aeb533e | 1344 | // 'sendbit' - 1 bit to send (least significant byte) |
IanBenzMaxim | 21:00c94aeb533e | 1345 | // |
IanBenzMaxim | 21:00c94aeb533e | 1346 | OneWireMaster::CmdResult DS2465::OWWriteBit(uint8_t sendbit) |
IanBenzMaxim | 21:00c94aeb533e | 1347 | { |
IanBenzMaxim | 21:00c94aeb533e | 1348 | return OWTouchBit(sendbit); |
IanBenzMaxim | 21:00c94aeb533e | 1349 | } |
IanBenzMaxim | 21:00c94aeb533e | 1350 | |
IanBenzMaxim | 21:00c94aeb533e | 1351 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 1352 | // |
IanBenzMaxim | 21:00c94aeb533e | 1353 | // |
IanBenzMaxim | 21:00c94aeb533e | 1354 | // |
IanBenzMaxim | 21:00c94aeb533e | 1355 | // |
IanBenzMaxim | 21:00c94aeb533e | 1356 | // |
IanBenzMaxim | 21:00c94aeb533e | 1357 | // |
IanBenzMaxim | 21:00c94aeb533e | 1358 | // |
IanBenzMaxim | 21:00c94aeb533e | 1359 | // Returns: |
IanBenzMaxim | 21:00c94aeb533e | 1360 | // |
IanBenzMaxim | 21:00c94aeb533e | 1361 | // |
IanBenzMaxim | 21:00c94aeb533e | 1362 | OneWireMaster::CmdResult DS2465::Write_Command_Reg(unsigned char cmd, unsigned char par, bool poll) const |
IanBenzMaxim | 21:00c94aeb533e | 1363 | { |
IanBenzMaxim | 21:00c94aeb533e | 1364 | int poll_count = 0, status; |
IanBenzMaxim | 21:00c94aeb533e | 1365 | |
IanBenzMaxim | 21:00c94aeb533e | 1366 | // Generic command |
IanBenzMaxim | 21:00c94aeb533e | 1367 | // S AD,0 [A] ADDR_CMD_REG [A] CMD [A] PP [A] P |
IanBenzMaxim | 21:00c94aeb533e | 1368 | // [] indicates from slave |
IanBenzMaxim | 21:00c94aeb533e | 1369 | // CMD command |
IanBenzMaxim | 21:00c94aeb533e | 1370 | // PP parameter |
IanBenzMaxim | 21:00c94aeb533e | 1371 | |
IanBenzMaxim | 21:00c94aeb533e | 1372 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 1373 | if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1374 | { |
IanBenzMaxim | 21:00c94aeb533e | 1375 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1376 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1377 | } |
IanBenzMaxim | 21:00c94aeb533e | 1378 | if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1379 | { |
IanBenzMaxim | 21:00c94aeb533e | 1380 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1381 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1382 | } |
IanBenzMaxim | 21:00c94aeb533e | 1383 | if (m_I2C_interface.write(cmd) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1384 | { |
IanBenzMaxim | 21:00c94aeb533e | 1385 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1386 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1387 | } |
IanBenzMaxim | 21:00c94aeb533e | 1388 | if (m_I2C_interface.write(par) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1389 | { |
IanBenzMaxim | 21:00c94aeb533e | 1390 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1391 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1392 | } |
IanBenzMaxim | 21:00c94aeb533e | 1393 | |
IanBenzMaxim | 21:00c94aeb533e | 1394 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1395 | |
IanBenzMaxim | 21:00c94aeb533e | 1396 | poll_count = 0; |
IanBenzMaxim | 21:00c94aeb533e | 1397 | if (poll) |
IanBenzMaxim | 21:00c94aeb533e | 1398 | { |
IanBenzMaxim | 21:00c94aeb533e | 1399 | // Poll for completion by checking for NAK on address |
IanBenzMaxim | 21:00c94aeb533e | 1400 | do |
IanBenzMaxim | 21:00c94aeb533e | 1401 | { |
IanBenzMaxim | 21:00c94aeb533e | 1402 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 1403 | status = m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)); |
IanBenzMaxim | 21:00c94aeb533e | 1404 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1405 | } while ((status != I2C_WRITE_OK) && (poll_count++ < POLL_LIMIT)); |
IanBenzMaxim | 21:00c94aeb533e | 1406 | } |
IanBenzMaxim | 21:00c94aeb533e | 1407 | else |
IanBenzMaxim | 21:00c94aeb533e | 1408 | { |
IanBenzMaxim | 21:00c94aeb533e | 1409 | // delay instead of poll, longest operation (only for SHA compute) |
IanBenzMaxim | 21:00c94aeb533e | 1410 | wait_ms(SHA_COMPUTATION_DELAY * 2); |
IanBenzMaxim | 21:00c94aeb533e | 1411 | wait_ms(8); // Additional delay |
IanBenzMaxim | 21:00c94aeb533e | 1412 | } |
IanBenzMaxim | 21:00c94aeb533e | 1413 | |
IanBenzMaxim | 21:00c94aeb533e | 1414 | // check for failure due to poll limit reached |
IanBenzMaxim | 21:00c94aeb533e | 1415 | if (poll_count >= POLL_LIMIT) |
IanBenzMaxim | 21:00c94aeb533e | 1416 | { |
IanBenzMaxim | 21:00c94aeb533e | 1417 | // handle error |
IanBenzMaxim | 21:00c94aeb533e | 1418 | // ... |
IanBenzMaxim | 21:00c94aeb533e | 1419 | //Reset(); |
IanBenzMaxim | 21:00c94aeb533e | 1420 | return OneWireMaster::TimeoutError; |
IanBenzMaxim | 21:00c94aeb533e | 1421 | } |
IanBenzMaxim | 21:00c94aeb533e | 1422 | |
IanBenzMaxim | 21:00c94aeb533e | 1423 | return OneWireMaster::Success; |
IanBenzMaxim | 21:00c94aeb533e | 1424 | } |
IanBenzMaxim | 21:00c94aeb533e | 1425 | |
IanBenzMaxim | 21:00c94aeb533e | 1426 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 1427 | // Write to Scratchpad (SRAM) memory on the DS2465 |
IanBenzMaxim | 21:00c94aeb533e | 1428 | // |
IanBenzMaxim | 21:00c94aeb533e | 1429 | // 'addr' - address to start writing (must be in SRAM) |
IanBenzMaxim | 21:00c94aeb533e | 1430 | // 'buf' - buffer of data to write |
IanBenzMaxim | 21:00c94aeb533e | 1431 | // 'len' - length to write |
IanBenzMaxim | 21:00c94aeb533e | 1432 | // |
IanBenzMaxim | 21:00c94aeb533e | 1433 | // Returns: true write successful |
IanBenzMaxim | 21:00c94aeb533e | 1434 | // false failure to complete write |
IanBenzMaxim | 21:00c94aeb533e | 1435 | // |
IanBenzMaxim | 21:00c94aeb533e | 1436 | OneWireMaster::CmdResult DS2465::WriteScratchpad(std::uint8_t addr, const std::uint8_t * buf, size_t bufLen) const |
IanBenzMaxim | 21:00c94aeb533e | 1437 | { |
IanBenzMaxim | 21:00c94aeb533e | 1438 | int i; |
IanBenzMaxim | 21:00c94aeb533e | 1439 | |
IanBenzMaxim | 21:00c94aeb533e | 1440 | // Write SRAM (Case A) |
IanBenzMaxim | 21:00c94aeb533e | 1441 | // S AD,0 [A] VSA [A] DD [A] P |
IanBenzMaxim | 21:00c94aeb533e | 1442 | // \-----/ |
IanBenzMaxim | 21:00c94aeb533e | 1443 | // Repeat for each data byte |
IanBenzMaxim | 21:00c94aeb533e | 1444 | // [] indicates from slave |
IanBenzMaxim | 21:00c94aeb533e | 1445 | // VSA valid SRAM memory address |
IanBenzMaxim | 21:00c94aeb533e | 1446 | // DD memory data to write |
IanBenzMaxim | 21:00c94aeb533e | 1447 | |
IanBenzMaxim | 21:00c94aeb533e | 1448 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 1449 | if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1450 | { |
IanBenzMaxim | 21:00c94aeb533e | 1451 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1452 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1453 | } |
IanBenzMaxim | 21:00c94aeb533e | 1454 | if (m_I2C_interface.write((unsigned char)addr) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1455 | { |
IanBenzMaxim | 21:00c94aeb533e | 1456 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1457 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1458 | } |
IanBenzMaxim | 21:00c94aeb533e | 1459 | // loop to write each byte |
IanBenzMaxim | 21:00c94aeb533e | 1460 | for (i = 0; i < bufLen; i++) |
IanBenzMaxim | 21:00c94aeb533e | 1461 | { |
IanBenzMaxim | 21:00c94aeb533e | 1462 | if (m_I2C_interface.write(buf[i]) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1463 | { |
IanBenzMaxim | 21:00c94aeb533e | 1464 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1465 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1466 | } |
IanBenzMaxim | 21:00c94aeb533e | 1467 | } |
IanBenzMaxim | 21:00c94aeb533e | 1468 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1469 | |
IanBenzMaxim | 21:00c94aeb533e | 1470 | return OneWireMaster::Success; |
IanBenzMaxim | 21:00c94aeb533e | 1471 | } |
IanBenzMaxim | 21:00c94aeb533e | 1472 | |
IanBenzMaxim | 21:00c94aeb533e | 1473 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 1474 | // Read memory from the DS2465 |
IanBenzMaxim | 21:00c94aeb533e | 1475 | // |
IanBenzMaxim | 21:00c94aeb533e | 1476 | // 'addr' - address to start reading |
IanBenzMaxim | 21:00c94aeb533e | 1477 | // 'buf' - buffer to hold memory read |
IanBenzMaxim | 21:00c94aeb533e | 1478 | // 'len' - length to read |
IanBenzMaxim | 21:00c94aeb533e | 1479 | // 'skip_set_pointer' - flag to indicate to skip setting address pointer |
IanBenzMaxim | 21:00c94aeb533e | 1480 | // |
IanBenzMaxim | 21:00c94aeb533e | 1481 | // Returns: true read successful |
IanBenzMaxim | 21:00c94aeb533e | 1482 | // false failure to complete read |
IanBenzMaxim | 21:00c94aeb533e | 1483 | // |
IanBenzMaxim | 21:00c94aeb533e | 1484 | OneWireMaster::CmdResult DS2465::ReadMemory(std::uint8_t addr, std::uint8_t * buf, size_t bufLen, bool skip_set_pointer) const |
IanBenzMaxim | 21:00c94aeb533e | 1485 | { |
IanBenzMaxim | 21:00c94aeb533e | 1486 | int i; |
IanBenzMaxim | 21:00c94aeb533e | 1487 | |
IanBenzMaxim | 21:00c94aeb533e | 1488 | // Read (Case A) |
IanBenzMaxim | 21:00c94aeb533e | 1489 | // S AD,0 [A] MA [A] Sr AD,1 [A] [DD] A [DD] A\ P |
IanBenzMaxim | 21:00c94aeb533e | 1490 | // \-----/ |
IanBenzMaxim | 21:00c94aeb533e | 1491 | // Repeat for each data byte, NAK last byte |
IanBenzMaxim | 21:00c94aeb533e | 1492 | // [] indicates from slave |
IanBenzMaxim | 21:00c94aeb533e | 1493 | // MA memory address |
IanBenzMaxim | 21:00c94aeb533e | 1494 | // DD memory data read |
IanBenzMaxim | 21:00c94aeb533e | 1495 | |
IanBenzMaxim | 21:00c94aeb533e | 1496 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 1497 | if (!skip_set_pointer) |
IanBenzMaxim | 21:00c94aeb533e | 1498 | { |
IanBenzMaxim | 21:00c94aeb533e | 1499 | if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1500 | { |
IanBenzMaxim | 21:00c94aeb533e | 1501 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1502 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1503 | } |
IanBenzMaxim | 21:00c94aeb533e | 1504 | if (m_I2C_interface.write((unsigned char)addr) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1505 | { |
IanBenzMaxim | 21:00c94aeb533e | 1506 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1507 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1508 | } |
IanBenzMaxim | 21:00c94aeb533e | 1509 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 1510 | } |
IanBenzMaxim | 21:00c94aeb533e | 1511 | |
IanBenzMaxim | 21:00c94aeb533e | 1512 | if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_READ)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1513 | { |
IanBenzMaxim | 21:00c94aeb533e | 1514 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1515 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1516 | } |
IanBenzMaxim | 21:00c94aeb533e | 1517 | // loop to read each byte, NAK last byte |
IanBenzMaxim | 21:00c94aeb533e | 1518 | for (i = 0; i < bufLen; i++) |
IanBenzMaxim | 21:00c94aeb533e | 1519 | { |
IanBenzMaxim | 21:00c94aeb533e | 1520 | buf[i] = m_I2C_interface.read((i == (bufLen - 1)) ? m_I2C_interface.NoACK : m_I2C_interface.ACK); |
IanBenzMaxim | 21:00c94aeb533e | 1521 | } |
IanBenzMaxim | 21:00c94aeb533e | 1522 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1523 | |
IanBenzMaxim | 21:00c94aeb533e | 1524 | return OneWireMaster::Success; |
IanBenzMaxim | 21:00c94aeb533e | 1525 | } |
IanBenzMaxim | 21:00c94aeb533e | 1526 | |
IanBenzMaxim | 21:00c94aeb533e | 1527 | |
IanBenzMaxim | 21:00c94aeb533e | 1528 | |
IanBenzMaxim | 21:00c94aeb533e | 1529 | |
IanBenzMaxim | 21:00c94aeb533e | 1530 | |
IanBenzMaxim | 21:00c94aeb533e | 1531 | OneWireMaster::CmdResult DS2465::ReadOneWireConfig(OWConfigAddr addr, std::uint8_t & config) const |
IanBenzMaxim | 21:00c94aeb533e | 1532 | { |
IanBenzMaxim | 21:00c94aeb533e | 1533 | std::uint8_t buf; |
IanBenzMaxim | 21:00c94aeb533e | 1534 | OneWireMaster::CmdResult result = ReadMemory(addr, &buf, 1, false); |
IanBenzMaxim | 21:00c94aeb533e | 1535 | if (result == OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 1536 | config = buf; |
IanBenzMaxim | 21:00c94aeb533e | 1537 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 1538 | } |
IanBenzMaxim | 21:00c94aeb533e | 1539 | |
IanBenzMaxim | 21:00c94aeb533e | 1540 | |
IanBenzMaxim | 21:00c94aeb533e | 1541 | |
IanBenzMaxim | 21:00c94aeb533e | 1542 | |
IanBenzMaxim | 21:00c94aeb533e | 1543 | |
IanBenzMaxim | 21:00c94aeb533e | 1544 | OneWireMaster::CmdResult DS2465::WriteOneWireConfig(OWConfigAddr addr, unsigned int ovr, unsigned int std) |
IanBenzMaxim | 21:00c94aeb533e | 1545 | { |
IanBenzMaxim | 21:00c94aeb533e | 1546 | std::uint8_t buf; |
IanBenzMaxim | 21:00c94aeb533e | 1547 | |
IanBenzMaxim | 21:00c94aeb533e | 1548 | // convert and write value |
IanBenzMaxim | 21:00c94aeb533e | 1549 | buf = (ovr << 4) | std; |
IanBenzMaxim | 21:00c94aeb533e | 1550 | return (WriteScratchpad(addr, &buf, 1)); |
IanBenzMaxim | 21:00c94aeb533e | 1551 | } |
IanBenzMaxim | 21:00c94aeb533e | 1552 | |
IanBenzMaxim | 21:00c94aeb533e | 1553 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 1554 | // Write the configuration register in the DS2465. The configuration |
IanBenzMaxim | 21:00c94aeb533e | 1555 | // options are provided in the lower nibble of the provided config byte. |
IanBenzMaxim | 21:00c94aeb533e | 1556 | // The uppper nibble in bitwise inverted when written to the DS2465. |
IanBenzMaxim | 21:00c94aeb533e | 1557 | // |
IanBenzMaxim | 21:00c94aeb533e | 1558 | // Returns: true: config written and response correct |
IanBenzMaxim | 21:00c94aeb533e | 1559 | // false: response incorrect |
IanBenzMaxim | 21:00c94aeb533e | 1560 | // |
IanBenzMaxim | 21:00c94aeb533e | 1561 | OneWireMaster::CmdResult DS2465::Write_Config(uint8_t config) |
IanBenzMaxim | 21:00c94aeb533e | 1562 | { |
IanBenzMaxim | 21:00c94aeb533e | 1563 | unsigned char read_config; |
IanBenzMaxim | 21:00c94aeb533e | 1564 | |
IanBenzMaxim | 21:00c94aeb533e | 1565 | // Write configuration byte |
IanBenzMaxim | 21:00c94aeb533e | 1566 | // S AD,0 [A] ADDR_WCFG_REG [A] CONIG [A] P |
IanBenzMaxim | 21:00c94aeb533e | 1567 | // [] indicates from slave |
IanBenzMaxim | 21:00c94aeb533e | 1568 | // CF configuration byte to write |
IanBenzMaxim | 21:00c94aeb533e | 1569 | |
IanBenzMaxim | 21:00c94aeb533e | 1570 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 1571 | |
IanBenzMaxim | 21:00c94aeb533e | 1572 | if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1573 | { |
IanBenzMaxim | 21:00c94aeb533e | 1574 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1575 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1576 | } |
IanBenzMaxim | 21:00c94aeb533e | 1577 | if (m_I2C_interface.write(ADDR_WCFG_REG) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1578 | { |
IanBenzMaxim | 21:00c94aeb533e | 1579 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1580 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1581 | } |
IanBenzMaxim | 21:00c94aeb533e | 1582 | if (m_I2C_interface.write((unsigned char)(config | (~config << 4))) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1583 | { |
IanBenzMaxim | 21:00c94aeb533e | 1584 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1585 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1586 | } |
IanBenzMaxim | 21:00c94aeb533e | 1587 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1588 | |
IanBenzMaxim | 21:00c94aeb533e | 1589 | // read it back to confirm |
j3 | 22:686273e55cdc | 1590 | // S AD,0 [A] ADDR_WCFG_REG [A] Sr AD,1 [A] [CF] A |
IanBenzMaxim | 21:00c94aeb533e | 1591 | |
IanBenzMaxim | 21:00c94aeb533e | 1592 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 1593 | if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1594 | { |
IanBenzMaxim | 21:00c94aeb533e | 1595 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1596 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1597 | } |
IanBenzMaxim | 21:00c94aeb533e | 1598 | if (m_I2C_interface.write(ADDR_WCFG_REG) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1599 | { |
IanBenzMaxim | 21:00c94aeb533e | 1600 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1601 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1602 | } |
IanBenzMaxim | 21:00c94aeb533e | 1603 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 1604 | if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_READ)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1605 | { |
IanBenzMaxim | 21:00c94aeb533e | 1606 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1607 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1608 | } |
IanBenzMaxim | 21:00c94aeb533e | 1609 | read_config = m_I2C_interface.read(m_I2C_interface.NoACK); |
IanBenzMaxim | 21:00c94aeb533e | 1610 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1611 | |
IanBenzMaxim | 21:00c94aeb533e | 1612 | |
IanBenzMaxim | 21:00c94aeb533e | 1613 | // check for failure due to incorrect read back |
IanBenzMaxim | 21:00c94aeb533e | 1614 | if (config != read_config) |
IanBenzMaxim | 21:00c94aeb533e | 1615 | { |
IanBenzMaxim | 21:00c94aeb533e | 1616 | // handle error |
IanBenzMaxim | 21:00c94aeb533e | 1617 | // ... |
IanBenzMaxim | 21:00c94aeb533e | 1618 | //Reset(); |
IanBenzMaxim | 21:00c94aeb533e | 1619 | |
IanBenzMaxim | 21:00c94aeb533e | 1620 | return OneWireMaster::TimeoutError; |
IanBenzMaxim | 21:00c94aeb533e | 1621 | } |
IanBenzMaxim | 21:00c94aeb533e | 1622 | |
IanBenzMaxim | 21:00c94aeb533e | 1623 | return OneWireMaster::Success; |
IanBenzMaxim | 21:00c94aeb533e | 1624 | } |
IanBenzMaxim | 21:00c94aeb533e | 1625 | |
IanBenzMaxim | 21:00c94aeb533e | 1626 | //-------------------------------------------------------------------------- |
IanBenzMaxim | 21:00c94aeb533e | 1627 | // Reset all of the devices on the 1-Wire Net and return the result. |
IanBenzMaxim | 21:00c94aeb533e | 1628 | // |
IanBenzMaxim | 21:00c94aeb533e | 1629 | // Returns: true(1): presense pulse(s) detected, device(s) reset |
IanBenzMaxim | 21:00c94aeb533e | 1630 | // false(0): no presense pulses detected |
IanBenzMaxim | 21:00c94aeb533e | 1631 | // |
IanBenzMaxim | 21:00c94aeb533e | 1632 | OneWireMaster::CmdResult DS2465::OWReset(void) |
IanBenzMaxim | 21:00c94aeb533e | 1633 | { |
IanBenzMaxim | 21:00c94aeb533e | 1634 | unsigned char status; |
IanBenzMaxim | 21:00c94aeb533e | 1635 | int poll_count = 0; |
IanBenzMaxim | 21:00c94aeb533e | 1636 | |
IanBenzMaxim | 21:00c94aeb533e | 1637 | // 1-Wire reset (Case B) |
IanBenzMaxim | 21:00c94aeb533e | 1638 | // S AD,0 [A] ADDR_CMD_REG [A] 1WRS [A] Sr AD,1 [A] [Status] A [Status] A\ P |
IanBenzMaxim | 21:00c94aeb533e | 1639 | // \--------/ |
IanBenzMaxim | 21:00c94aeb533e | 1640 | // Repeat until 1WB bit has changed to 0 |
IanBenzMaxim | 21:00c94aeb533e | 1641 | // [] indicates from slave |
IanBenzMaxim | 21:00c94aeb533e | 1642 | |
IanBenzMaxim | 21:00c94aeb533e | 1643 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 1644 | |
IanBenzMaxim | 21:00c94aeb533e | 1645 | if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1646 | { |
IanBenzMaxim | 21:00c94aeb533e | 1647 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1648 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1649 | } |
IanBenzMaxim | 21:00c94aeb533e | 1650 | if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1651 | { |
IanBenzMaxim | 21:00c94aeb533e | 1652 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1653 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1654 | } |
IanBenzMaxim | 21:00c94aeb533e | 1655 | if (m_I2C_interface.write(CMD_1WRS) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1656 | { |
IanBenzMaxim | 21:00c94aeb533e | 1657 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1658 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1659 | } |
IanBenzMaxim | 21:00c94aeb533e | 1660 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 1661 | if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_READ)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1662 | { |
IanBenzMaxim | 21:00c94aeb533e | 1663 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1664 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1665 | } |
IanBenzMaxim | 21:00c94aeb533e | 1666 | |
IanBenzMaxim | 21:00c94aeb533e | 1667 | // loop checking 1WB bit for completion of 1-Wire operation |
IanBenzMaxim | 21:00c94aeb533e | 1668 | // abort if poll limit reached |
IanBenzMaxim | 21:00c94aeb533e | 1669 | status = STATUS_1WB; |
IanBenzMaxim | 21:00c94aeb533e | 1670 | while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT)) |
IanBenzMaxim | 21:00c94aeb533e | 1671 | { |
IanBenzMaxim | 21:00c94aeb533e | 1672 | status = m_I2C_interface.read(m_I2C_interface.ACK); |
IanBenzMaxim | 21:00c94aeb533e | 1673 | } |
IanBenzMaxim | 21:00c94aeb533e | 1674 | |
IanBenzMaxim | 21:00c94aeb533e | 1675 | // one last read with NACK |
IanBenzMaxim | 21:00c94aeb533e | 1676 | m_I2C_interface.read(m_I2C_interface.NoACK); |
IanBenzMaxim | 21:00c94aeb533e | 1677 | |
IanBenzMaxim | 21:00c94aeb533e | 1678 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1679 | |
IanBenzMaxim | 21:00c94aeb533e | 1680 | // check for failure due to poll limit reached |
IanBenzMaxim | 21:00c94aeb533e | 1681 | if (poll_count >= POLL_LIMIT) |
IanBenzMaxim | 21:00c94aeb533e | 1682 | { |
IanBenzMaxim | 21:00c94aeb533e | 1683 | // handle error |
IanBenzMaxim | 21:00c94aeb533e | 1684 | // ... |
IanBenzMaxim | 21:00c94aeb533e | 1685 | //Reset(); |
IanBenzMaxim | 21:00c94aeb533e | 1686 | return OneWireMaster::TimeoutError; |
IanBenzMaxim | 21:00c94aeb533e | 1687 | } |
IanBenzMaxim | 21:00c94aeb533e | 1688 | |
IanBenzMaxim | 21:00c94aeb533e | 1689 | // check for short condition |
IanBenzMaxim | 21:00c94aeb533e | 1690 | if (status & STATUS_SD) |
IanBenzMaxim | 21:00c94aeb533e | 1691 | short_detected = true; |
IanBenzMaxim | 21:00c94aeb533e | 1692 | else |
IanBenzMaxim | 21:00c94aeb533e | 1693 | short_detected = false; |
IanBenzMaxim | 21:00c94aeb533e | 1694 | |
IanBenzMaxim | 21:00c94aeb533e | 1695 | |
IanBenzMaxim | 21:00c94aeb533e | 1696 | // check for presence detect |
IanBenzMaxim | 21:00c94aeb533e | 1697 | if (status & STATUS_PPD) |
IanBenzMaxim | 21:00c94aeb533e | 1698 | return OneWireMaster::Success; |
IanBenzMaxim | 21:00c94aeb533e | 1699 | // else |
IanBenzMaxim | 21:00c94aeb533e | 1700 | return OneWireMaster::OperationFailure; |
IanBenzMaxim | 21:00c94aeb533e | 1701 | } |
IanBenzMaxim | 21:00c94aeb533e | 1702 | |
IanBenzMaxim | 21:00c94aeb533e | 1703 | OneWireMaster::CmdResult DS2465::Reset(void) |
IanBenzMaxim | 21:00c94aeb533e | 1704 | { |
IanBenzMaxim | 21:00c94aeb533e | 1705 | uint8_t status; |
IanBenzMaxim | 21:00c94aeb533e | 1706 | |
IanBenzMaxim | 21:00c94aeb533e | 1707 | // Device Reset |
IanBenzMaxim | 21:00c94aeb533e | 1708 | // S AD,0 [A] ADDR_CMD_REG [A] 1WMR [A] Sr AD,1 [A] [SS] A\ P |
IanBenzMaxim | 21:00c94aeb533e | 1709 | // [] indicates from slave |
IanBenzMaxim | 21:00c94aeb533e | 1710 | // SS status byte to read to verify state |
IanBenzMaxim | 21:00c94aeb533e | 1711 | |
IanBenzMaxim | 21:00c94aeb533e | 1712 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 1713 | |
IanBenzMaxim | 21:00c94aeb533e | 1714 | if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1715 | { |
IanBenzMaxim | 21:00c94aeb533e | 1716 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1717 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1718 | } |
IanBenzMaxim | 21:00c94aeb533e | 1719 | |
IanBenzMaxim | 21:00c94aeb533e | 1720 | if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1721 | { |
IanBenzMaxim | 21:00c94aeb533e | 1722 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1723 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1724 | } |
IanBenzMaxim | 21:00c94aeb533e | 1725 | |
IanBenzMaxim | 21:00c94aeb533e | 1726 | if (m_I2C_interface.write(CMD_1WMR) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1727 | { |
IanBenzMaxim | 21:00c94aeb533e | 1728 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1729 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1730 | } |
IanBenzMaxim | 21:00c94aeb533e | 1731 | |
IanBenzMaxim | 21:00c94aeb533e | 1732 | m_I2C_interface.start(); |
IanBenzMaxim | 21:00c94aeb533e | 1733 | |
IanBenzMaxim | 21:00c94aeb533e | 1734 | if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_READ)) != I2C_WRITE_OK) |
IanBenzMaxim | 21:00c94aeb533e | 1735 | { |
IanBenzMaxim | 21:00c94aeb533e | 1736 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1737 | return OneWireMaster::CommunicationWriteError; |
IanBenzMaxim | 21:00c94aeb533e | 1738 | } |
IanBenzMaxim | 21:00c94aeb533e | 1739 | |
IanBenzMaxim | 21:00c94aeb533e | 1740 | status = m_I2C_interface.read(m_I2C_interface.NoACK); |
IanBenzMaxim | 21:00c94aeb533e | 1741 | |
IanBenzMaxim | 21:00c94aeb533e | 1742 | m_I2C_interface.stop(); |
IanBenzMaxim | 21:00c94aeb533e | 1743 | |
IanBenzMaxim | 21:00c94aeb533e | 1744 | // do a command to get 1-Wire master reset out of holding state |
IanBenzMaxim | 21:00c94aeb533e | 1745 | OWReset(); |
IanBenzMaxim | 21:00c94aeb533e | 1746 | |
IanBenzMaxim | 21:00c94aeb533e | 1747 | // check for failure due to incorrect read back of status |
IanBenzMaxim | 21:00c94aeb533e | 1748 | return ((status & 0xF7) == 0x10) ? OneWireMaster::Success : OneWireMaster::OperationFailure; |
IanBenzMaxim | 21:00c94aeb533e | 1749 | } |
IanBenzMaxim | 21:00c94aeb533e | 1750 | |
IanBenzMaxim | 21:00c94aeb533e | 1751 | OneWireMaster::CmdResult DS2465::Detect(void) |
IanBenzMaxim | 21:00c94aeb533e | 1752 | { |
IanBenzMaxim | 21:00c94aeb533e | 1753 | OneWireMaster::CmdResult result; |
IanBenzMaxim | 21:00c94aeb533e | 1754 | |
IanBenzMaxim | 21:00c94aeb533e | 1755 | // reset DS2465 |
IanBenzMaxim | 21:00c94aeb533e | 1756 | result = Reset(); |
IanBenzMaxim | 21:00c94aeb533e | 1757 | if (result != OneWireMaster::Success) |
IanBenzMaxim | 21:00c94aeb533e | 1758 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 1759 | |
IanBenzMaxim | 21:00c94aeb533e | 1760 | // default configuration |
IanBenzMaxim | 21:00c94aeb533e | 1761 | c1WS = 0; |
IanBenzMaxim | 21:00c94aeb533e | 1762 | cSPU = 0; |
IanBenzMaxim | 21:00c94aeb533e | 1763 | cPDN = 0; |
IanBenzMaxim | 21:00c94aeb533e | 1764 | cAPU = CONFIG_APU; |
IanBenzMaxim | 21:00c94aeb533e | 1765 | |
IanBenzMaxim | 21:00c94aeb533e | 1766 | // write the default configuration setup |
IanBenzMaxim | 21:00c94aeb533e | 1767 | result = Write_Config(c1WS | cSPU | cPDN | cAPU); |
IanBenzMaxim | 21:00c94aeb533e | 1768 | return result; |
IanBenzMaxim | 21:00c94aeb533e | 1769 | } |