Device interface library for multiple platforms including Mbed.

Dependents:   DeepCover Embedded Security in IoT MaximInterface MAXREFDES155#

Maxim Interface is a library framework focused on providing flexible and expressive hardware interfaces. Both communication interfaces such as I2C and 1-Wire and device interfaces such as DS18B20 are supported. Modern C++ concepts are used extensively while keeping compatibility with C++98/C++03 and requiring no external dependencies. The embedded-friendly design does not depend on exceptions or RTTI.

The full version of the project is hosted on GitLab: https://gitlab.com/iabenz/MaximInterface

Committer:
IanBenzMaxim
Date:
Fri May 29 16:19:22 2020 -0500
Revision:
12:7eb41621ba22
Parent:
11:3f3bf6bf5e6c
Updated to version 2.2.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
IanBenzMaxim 7:9cd16581b578 1 /*******************************************************************************
IanBenzMaxim 8:5ea891c7d1a1 2 * Copyright (C) Maxim Integrated Products, Inc., All Rights Reserved.
IanBenzMaxim 7:9cd16581b578 3 *
IanBenzMaxim 7:9cd16581b578 4 * Permission is hereby granted, free of charge, to any person obtaining a
IanBenzMaxim 7:9cd16581b578 5 * copy of this software and associated documentation files (the "Software"),
IanBenzMaxim 7:9cd16581b578 6 * to deal in the Software without restriction, including without limitation
IanBenzMaxim 7:9cd16581b578 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
IanBenzMaxim 7:9cd16581b578 8 * and/or sell copies of the Software, and to permit persons to whom the
IanBenzMaxim 7:9cd16581b578 9 * Software is furnished to do so, subject to the following conditions:
IanBenzMaxim 7:9cd16581b578 10 *
IanBenzMaxim 7:9cd16581b578 11 * The above copyright notice and this permission notice shall be included
IanBenzMaxim 7:9cd16581b578 12 * in all copies or substantial portions of the Software.
IanBenzMaxim 7:9cd16581b578 13 *
IanBenzMaxim 7:9cd16581b578 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
IanBenzMaxim 7:9cd16581b578 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
IanBenzMaxim 7:9cd16581b578 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IanBenzMaxim 7:9cd16581b578 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
IanBenzMaxim 7:9cd16581b578 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
IanBenzMaxim 7:9cd16581b578 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
IanBenzMaxim 7:9cd16581b578 20 * OTHER DEALINGS IN THE SOFTWARE.
IanBenzMaxim 7:9cd16581b578 21 *
IanBenzMaxim 7:9cd16581b578 22 * Except as contained in this notice, the name of Maxim Integrated
IanBenzMaxim 7:9cd16581b578 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
IanBenzMaxim 7:9cd16581b578 24 * Products, Inc. Branding Policy.
IanBenzMaxim 7:9cd16581b578 25 *
IanBenzMaxim 7:9cd16581b578 26 * The mere transfer of this software does not imply any licenses
IanBenzMaxim 7:9cd16581b578 27 * of trade secrets, proprietary technology, copyrights, patents,
IanBenzMaxim 7:9cd16581b578 28 * trademarks, maskwork rights, or any other form of intellectual
IanBenzMaxim 7:9cd16581b578 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
IanBenzMaxim 7:9cd16581b578 30 * ownership rights.
IanBenzMaxim 7:9cd16581b578 31 *******************************************************************************/
IanBenzMaxim 7:9cd16581b578 32
IanBenzMaxim 7:9cd16581b578 33 #include <MaximInterfaceCore/Error.hpp>
IanBenzMaxim 7:9cd16581b578 34 #include "DS2480B.hpp"
IanBenzMaxim 7:9cd16581b578 35
IanBenzMaxim 8:5ea891c7d1a1 36 #define TRY MaximInterfaceCore_TRY
IanBenzMaxim 8:5ea891c7d1a1 37 #define TRY_VALUE MaximInterfaceCore_TRY_VALUE
IanBenzMaxim 8:5ea891c7d1a1 38
IanBenzMaxim 7:9cd16581b578 39 // Mode Commands
IanBenzMaxim 7:9cd16581b578 40 #define MODE_DATA 0xE1
IanBenzMaxim 7:9cd16581b578 41 #define MODE_COMMAND 0xE3
IanBenzMaxim 7:9cd16581b578 42 #define MODE_STOP_PULSE 0xF1
IanBenzMaxim 7:9cd16581b578 43
IanBenzMaxim 7:9cd16581b578 44 // Return byte value
IanBenzMaxim 7:9cd16581b578 45 #define RB_CHIPID_MASK 0x1C
IanBenzMaxim 7:9cd16581b578 46 #define RB_RESET_MASK 0x03
IanBenzMaxim 7:9cd16581b578 47 #define RB_1WIRESHORT 0x00
IanBenzMaxim 7:9cd16581b578 48 #define RB_PRESENCE 0x01
IanBenzMaxim 7:9cd16581b578 49 #define RB_ALARMPRESENCE 0x02
IanBenzMaxim 7:9cd16581b578 50 #define RB_NOPRESENCE 0x03
IanBenzMaxim 7:9cd16581b578 51
IanBenzMaxim 7:9cd16581b578 52 #define RB_BIT_MASK 0x03
IanBenzMaxim 7:9cd16581b578 53 #define RB_BIT_ONE 0x03
IanBenzMaxim 7:9cd16581b578 54 #define RB_BIT_ZERO 0x00
IanBenzMaxim 7:9cd16581b578 55
IanBenzMaxim 7:9cd16581b578 56 // Masks for all bit ranges
IanBenzMaxim 7:9cd16581b578 57 #define CMD_MASK 0x80
IanBenzMaxim 7:9cd16581b578 58 #define FUNCTSEL_MASK 0x60
IanBenzMaxim 7:9cd16581b578 59 #define BITPOL_MASK 0x10
IanBenzMaxim 7:9cd16581b578 60 #define SPEEDSEL_MASK 0x0C
IanBenzMaxim 7:9cd16581b578 61 #define MODSEL_MASK 0x02
IanBenzMaxim 7:9cd16581b578 62 #define PARMSEL_MASK 0x70
IanBenzMaxim 7:9cd16581b578 63 #define PARMSET_MASK 0x0E
IanBenzMaxim 7:9cd16581b578 64
IanBenzMaxim 7:9cd16581b578 65 // Command or config bit
IanBenzMaxim 7:9cd16581b578 66 #define CMD_COMM 0x81
IanBenzMaxim 7:9cd16581b578 67 #define CMD_CONFIG 0x01
IanBenzMaxim 7:9cd16581b578 68
IanBenzMaxim 7:9cd16581b578 69 // Function select bits
IanBenzMaxim 7:9cd16581b578 70 #define FUNCTSEL_BIT 0x00
IanBenzMaxim 7:9cd16581b578 71 #define FUNCTSEL_SEARCHON 0x30
IanBenzMaxim 7:9cd16581b578 72 #define FUNCTSEL_SEARCHOFF 0x20
IanBenzMaxim 7:9cd16581b578 73 #define FUNCTSEL_RESET 0x40
IanBenzMaxim 7:9cd16581b578 74 #define FUNCTSEL_CHMOD 0x60
IanBenzMaxim 7:9cd16581b578 75
IanBenzMaxim 7:9cd16581b578 76 // Bit polarity/Pulse voltage bits
IanBenzMaxim 7:9cd16581b578 77 #define BITPOL_ONE 0x10
IanBenzMaxim 7:9cd16581b578 78 #define BITPOL_ZERO 0x00
IanBenzMaxim 7:9cd16581b578 79 #define BITPOL_5V 0x00
IanBenzMaxim 7:9cd16581b578 80 #define BITPOL_12V 0x10
IanBenzMaxim 7:9cd16581b578 81
IanBenzMaxim 7:9cd16581b578 82 // One Wire speed bits
IanBenzMaxim 7:9cd16581b578 83 #define SPEEDSEL_STD 0x00
IanBenzMaxim 7:9cd16581b578 84 #define SPEEDSEL_FLEX 0x04
IanBenzMaxim 7:9cd16581b578 85 #define SPEEDSEL_OD 0x08
IanBenzMaxim 7:9cd16581b578 86 #define SPEEDSEL_PULSE 0x0C
IanBenzMaxim 7:9cd16581b578 87
IanBenzMaxim 7:9cd16581b578 88 // Data/Command mode select bits
IanBenzMaxim 7:9cd16581b578 89 #define MODSEL_DATA 0x00
IanBenzMaxim 7:9cd16581b578 90 #define MODSEL_COMMAND 0x02
IanBenzMaxim 7:9cd16581b578 91
IanBenzMaxim 7:9cd16581b578 92 // 5V Follow Pulse select bits
IanBenzMaxim 7:9cd16581b578 93 #define PRIME5V_TRUE 0x02
IanBenzMaxim 7:9cd16581b578 94 #define PRIME5V_FALSE 0x00
IanBenzMaxim 7:9cd16581b578 95
IanBenzMaxim 7:9cd16581b578 96 // Parameter select bits
IanBenzMaxim 7:9cd16581b578 97 #define PARMSEL_PARMREAD 0x00
IanBenzMaxim 7:9cd16581b578 98 #define PARMSEL_SLEW 0x10
IanBenzMaxim 7:9cd16581b578 99 #define PARMSEL_12VPULSE 0x20
IanBenzMaxim 7:9cd16581b578 100 #define PARMSEL_5VPULSE 0x30
IanBenzMaxim 7:9cd16581b578 101 #define PARMSEL_WRITE1LOW 0x40
IanBenzMaxim 7:9cd16581b578 102 #define PARMSEL_SAMPLEOFFSET 0x50
IanBenzMaxim 7:9cd16581b578 103 #define PARMSEL_ACTIVEPULLUPTIME 0x60
IanBenzMaxim 7:9cd16581b578 104 #define PARMSEL_BAUDRATE 0x70
IanBenzMaxim 7:9cd16581b578 105
IanBenzMaxim 7:9cd16581b578 106 // Pull down slew rate.
IanBenzMaxim 7:9cd16581b578 107 #define PARMSET_Slew15Vus 0x00
IanBenzMaxim 7:9cd16581b578 108 #define PARMSET_Slew2p2Vus 0x02
IanBenzMaxim 7:9cd16581b578 109 #define PARMSET_Slew1p65Vus 0x04
IanBenzMaxim 7:9cd16581b578 110 #define PARMSET_Slew1p37Vus 0x06
IanBenzMaxim 7:9cd16581b578 111 #define PARMSET_Slew1p1Vus 0x08
IanBenzMaxim 7:9cd16581b578 112 #define PARMSET_Slew0p83Vus 0x0A
IanBenzMaxim 7:9cd16581b578 113 #define PARMSET_Slew0p7Vus 0x0C
IanBenzMaxim 7:9cd16581b578 114 #define PARMSET_Slew0p55Vus 0x0E
IanBenzMaxim 7:9cd16581b578 115
IanBenzMaxim 7:9cd16581b578 116 // 12V programming pulse time table
IanBenzMaxim 7:9cd16581b578 117 #define PARMSET_32us 0x00
IanBenzMaxim 7:9cd16581b578 118 #define PARMSET_64us 0x02
IanBenzMaxim 7:9cd16581b578 119 #define PARMSET_128us 0x04
IanBenzMaxim 7:9cd16581b578 120 #define PARMSET_256us 0x06
IanBenzMaxim 7:9cd16581b578 121 #define PARMSET_512us 0x08
IanBenzMaxim 7:9cd16581b578 122 #define PARMSET_1024us 0x0A
IanBenzMaxim 7:9cd16581b578 123 #define PARMSET_2048us 0x0C
IanBenzMaxim 7:9cd16581b578 124 #define PARMSET_infinite 0x0E
IanBenzMaxim 7:9cd16581b578 125
IanBenzMaxim 7:9cd16581b578 126 // 5V strong pull up pulse time table
IanBenzMaxim 7:9cd16581b578 127 #define PARMSET_16p4ms 0x00
IanBenzMaxim 7:9cd16581b578 128 #define PARMSET_65p5ms 0x02
IanBenzMaxim 7:9cd16581b578 129 #define PARMSET_131ms 0x04
IanBenzMaxim 7:9cd16581b578 130 #define PARMSET_262ms 0x06
IanBenzMaxim 7:9cd16581b578 131 #define PARMSET_524ms 0x08
IanBenzMaxim 7:9cd16581b578 132 #define PARMSET_1p05s 0x0A
IanBenzMaxim 7:9cd16581b578 133 #define PARMSET_dynamic 0x0C
IanBenzMaxim 7:9cd16581b578 134 #define PARMSET_infinite 0x0E
IanBenzMaxim 7:9cd16581b578 135
IanBenzMaxim 7:9cd16581b578 136 // Write 1 low time
IanBenzMaxim 7:9cd16581b578 137 #define PARMSET_Write8us 0x00
IanBenzMaxim 7:9cd16581b578 138 #define PARMSET_Write9us 0x02
IanBenzMaxim 7:9cd16581b578 139 #define PARMSET_Write10us 0x04
IanBenzMaxim 7:9cd16581b578 140 #define PARMSET_Write11us 0x06
IanBenzMaxim 7:9cd16581b578 141 #define PARMSET_Write12us 0x08
IanBenzMaxim 7:9cd16581b578 142 #define PARMSET_Write13us 0x0A
IanBenzMaxim 7:9cd16581b578 143 #define PARMSET_Write14us 0x0C
IanBenzMaxim 7:9cd16581b578 144 #define PARMSET_Write15us 0x0E
IanBenzMaxim 7:9cd16581b578 145
IanBenzMaxim 7:9cd16581b578 146 // Data sample offset and Write 0 recovery time
IanBenzMaxim 7:9cd16581b578 147 #define PARMSET_SampOff3us 0x00
IanBenzMaxim 7:9cd16581b578 148 #define PARMSET_SampOff4us 0x02
IanBenzMaxim 7:9cd16581b578 149 #define PARMSET_SampOff5us 0x04
IanBenzMaxim 7:9cd16581b578 150 #define PARMSET_SampOff6us 0x06
IanBenzMaxim 7:9cd16581b578 151 #define PARMSET_SampOff7us 0x08
IanBenzMaxim 7:9cd16581b578 152 #define PARMSET_SampOff8us 0x0A
IanBenzMaxim 7:9cd16581b578 153 #define PARMSET_SampOff9us 0x0C
IanBenzMaxim 7:9cd16581b578 154 #define PARMSET_SampOff10us 0x0E
IanBenzMaxim 7:9cd16581b578 155
IanBenzMaxim 7:9cd16581b578 156 // Active pull up on time
IanBenzMaxim 7:9cd16581b578 157 #define PARMSET_PullUp0p0us 0x00
IanBenzMaxim 7:9cd16581b578 158 #define PARMSET_PullUp0p5us 0x02
IanBenzMaxim 7:9cd16581b578 159 #define PARMSET_PullUp1p0us 0x04
IanBenzMaxim 7:9cd16581b578 160 #define PARMSET_PullUp1p5us 0x06
IanBenzMaxim 7:9cd16581b578 161 #define PARMSET_PullUp2p0us 0x08
IanBenzMaxim 7:9cd16581b578 162 #define PARMSET_PullUp2p5us 0x0A
IanBenzMaxim 7:9cd16581b578 163 #define PARMSET_PullUp3p0us 0x0C
IanBenzMaxim 7:9cd16581b578 164 #define PARMSET_PullUp3p5us 0x0E
IanBenzMaxim 7:9cd16581b578 165
IanBenzMaxim 7:9cd16581b578 166 // Baud rate bits
IanBenzMaxim 7:9cd16581b578 167 #define PARMSET_9600 0x00
IanBenzMaxim 7:9cd16581b578 168 #define PARMSET_19200 0x02
IanBenzMaxim 7:9cd16581b578 169 #define PARMSET_57600 0x04
IanBenzMaxim 7:9cd16581b578 170 #define PARMSET_115200 0x06
IanBenzMaxim 7:9cd16581b578 171
IanBenzMaxim 7:9cd16581b578 172 // DS2480B program voltage available
IanBenzMaxim 7:9cd16581b578 173 #define DS2480BPROG_MASK 0x20
IanBenzMaxim 7:9cd16581b578 174
IanBenzMaxim 7:9cd16581b578 175 namespace MaximInterfaceDevices {
IanBenzMaxim 7:9cd16581b578 176
IanBenzMaxim 7:9cd16581b578 177 using namespace Core;
IanBenzMaxim 7:9cd16581b578 178
IanBenzMaxim 8:5ea891c7d1a1 179 Result<void> DS2480B::initialize() {
IanBenzMaxim 7:9cd16581b578 180 level = NormalLevel;
IanBenzMaxim 7:9cd16581b578 181 mode = MODSEL_COMMAND;
IanBenzMaxim 7:9cd16581b578 182 speed = SPEEDSEL_STD;
IanBenzMaxim 7:9cd16581b578 183
IanBenzMaxim 7:9cd16581b578 184 // Send a break to reset the DS2480B.
IanBenzMaxim 7:9cd16581b578 185 // Switch to lower baud rate to ensure break is longer than 2 ms.
IanBenzMaxim 8:5ea891c7d1a1 186 Result<void> result = uart->setBaudRate(4800);
IanBenzMaxim 8:5ea891c7d1a1 187 if (!result) {
IanBenzMaxim 7:9cd16581b578 188 return result;
IanBenzMaxim 7:9cd16581b578 189 }
IanBenzMaxim 7:9cd16581b578 190 result = uart->sendBreak();
IanBenzMaxim 8:5ea891c7d1a1 191 if (!result) {
IanBenzMaxim 7:9cd16581b578 192 return result;
IanBenzMaxim 7:9cd16581b578 193 }
IanBenzMaxim 7:9cd16581b578 194 result = uart->setBaudRate(9600);
IanBenzMaxim 8:5ea891c7d1a1 195 if (!result) {
IanBenzMaxim 7:9cd16581b578 196 return result;
IanBenzMaxim 7:9cd16581b578 197 }
IanBenzMaxim 7:9cd16581b578 198
IanBenzMaxim 7:9cd16581b578 199 // Wait for master reset.
IanBenzMaxim 7:9cd16581b578 200 sleep->invoke(1);
IanBenzMaxim 7:9cd16581b578 201
IanBenzMaxim 7:9cd16581b578 202 // Flush the read buffer.
IanBenzMaxim 7:9cd16581b578 203 result = uart->clearReadBuffer();
IanBenzMaxim 8:5ea891c7d1a1 204 if (!result) {
IanBenzMaxim 7:9cd16581b578 205 return result;
IanBenzMaxim 7:9cd16581b578 206 }
IanBenzMaxim 7:9cd16581b578 207
IanBenzMaxim 7:9cd16581b578 208 // Send the timing byte.
IanBenzMaxim 7:9cd16581b578 209 result = uart->writeByte(CMD_COMM | FUNCTSEL_RESET | SPEEDSEL_STD);
IanBenzMaxim 8:5ea891c7d1a1 210 if (!result) {
IanBenzMaxim 7:9cd16581b578 211 return result;
IanBenzMaxim 7:9cd16581b578 212 }
IanBenzMaxim 7:9cd16581b578 213
IanBenzMaxim 7:9cd16581b578 214 // Change the DS2480 baud rate.
IanBenzMaxim 7:9cd16581b578 215 result = uart->writeByte(CMD_CONFIG | PARMSEL_BAUDRATE | PARMSET_115200);
IanBenzMaxim 8:5ea891c7d1a1 216 if (!result) {
IanBenzMaxim 7:9cd16581b578 217 return result;
IanBenzMaxim 7:9cd16581b578 218 }
IanBenzMaxim 7:9cd16581b578 219
IanBenzMaxim 7:9cd16581b578 220 // Change our baud rate.
IanBenzMaxim 7:9cd16581b578 221 result = uart->setBaudRate(115200);
IanBenzMaxim 8:5ea891c7d1a1 222 if (!result) {
IanBenzMaxim 7:9cd16581b578 223 return result;
IanBenzMaxim 7:9cd16581b578 224 }
IanBenzMaxim 7:9cd16581b578 225
IanBenzMaxim 8:5ea891c7d1a1 226 // Verify response.
IanBenzMaxim 7:9cd16581b578 227 uint_least8_t response;
IanBenzMaxim 8:5ea891c7d1a1 228 TRY_VALUE(response, uart->readByte());
IanBenzMaxim 7:9cd16581b578 229 if ((response & (PARMSEL_MASK | PARMSET_MASK)) !=
IanBenzMaxim 7:9cd16581b578 230 (PARMSEL_BAUDRATE | PARMSET_115200)) {
IanBenzMaxim 8:5ea891c7d1a1 231 return HardwareError;
IanBenzMaxim 7:9cd16581b578 232 }
IanBenzMaxim 7:9cd16581b578 233
IanBenzMaxim 7:9cd16581b578 234 // Set the SPUD time value.
IanBenzMaxim 7:9cd16581b578 235 result = uart->writeByte(CMD_CONFIG | PARMSEL_5VPULSE | PARMSET_infinite);
IanBenzMaxim 8:5ea891c7d1a1 236 if (!result) {
IanBenzMaxim 7:9cd16581b578 237 return result;
IanBenzMaxim 7:9cd16581b578 238 }
IanBenzMaxim 7:9cd16581b578 239
IanBenzMaxim 7:9cd16581b578 240 // Verify response.
IanBenzMaxim 8:5ea891c7d1a1 241 TRY_VALUE(response, uart->readByte());
IanBenzMaxim 7:9cd16581b578 242 if ((response & (PARMSEL_MASK | PARMSET_MASK)) !=
IanBenzMaxim 7:9cd16581b578 243 (PARMSEL_5VPULSE | PARMSET_infinite)) {
IanBenzMaxim 8:5ea891c7d1a1 244 return HardwareError;
IanBenzMaxim 7:9cd16581b578 245 }
IanBenzMaxim 7:9cd16581b578 246
IanBenzMaxim 7:9cd16581b578 247 return result;
IanBenzMaxim 7:9cd16581b578 248 }
IanBenzMaxim 7:9cd16581b578 249
IanBenzMaxim 8:5ea891c7d1a1 250 Result<void> DS2480B::reset() {
IanBenzMaxim 7:9cd16581b578 251 if (level != NormalLevel) {
IanBenzMaxim 8:5ea891c7d1a1 252 return InvalidLevelError;
IanBenzMaxim 7:9cd16581b578 253 }
IanBenzMaxim 7:9cd16581b578 254
IanBenzMaxim 7:9cd16581b578 255 uint_least8_t packet[2];
IanBenzMaxim 7:9cd16581b578 256 int packetLen = 0;
IanBenzMaxim 7:9cd16581b578 257
IanBenzMaxim 7:9cd16581b578 258 // Check for correct mode.
IanBenzMaxim 7:9cd16581b578 259 if (mode != MODSEL_COMMAND) {
IanBenzMaxim 7:9cd16581b578 260 mode = MODSEL_COMMAND;
IanBenzMaxim 7:9cd16581b578 261 packet[packetLen++] = MODE_COMMAND;
IanBenzMaxim 7:9cd16581b578 262 }
IanBenzMaxim 7:9cd16581b578 263
IanBenzMaxim 7:9cd16581b578 264 // Construct the command.
IanBenzMaxim 7:9cd16581b578 265 packet[packetLen++] = CMD_COMM | FUNCTSEL_RESET | speed;
IanBenzMaxim 7:9cd16581b578 266
IanBenzMaxim 7:9cd16581b578 267 // Send the packet.
IanBenzMaxim 8:5ea891c7d1a1 268 TRY(uart->writeBlock(make_span(packet, packetLen)));
IanBenzMaxim 7:9cd16581b578 269
IanBenzMaxim 7:9cd16581b578 270 // Read back the response.
IanBenzMaxim 8:5ea891c7d1a1 271 TRY_VALUE(packet[0], uart->readByte());
IanBenzMaxim 7:9cd16581b578 272
IanBenzMaxim 7:9cd16581b578 273 // Make sure this byte looks like a reset byte.
IanBenzMaxim 7:9cd16581b578 274 if ((packet[0] & RB_RESET_MASK) == RB_1WIRESHORT) {
IanBenzMaxim 8:5ea891c7d1a1 275 return ShortDetectedError;
IanBenzMaxim 7:9cd16581b578 276 }
IanBenzMaxim 8:5ea891c7d1a1 277 if ((packet[0] & RB_RESET_MASK) == RB_NOPRESENCE) {
IanBenzMaxim 8:5ea891c7d1a1 278 return NoSlaveError;
IanBenzMaxim 8:5ea891c7d1a1 279 }
IanBenzMaxim 8:5ea891c7d1a1 280
IanBenzMaxim 8:5ea891c7d1a1 281 return none;
IanBenzMaxim 7:9cd16581b578 282 }
IanBenzMaxim 7:9cd16581b578 283
IanBenzMaxim 8:5ea891c7d1a1 284 Result<bool> DS2480B::touchBitSetLevel(bool sendBit, Level afterLevel) {
IanBenzMaxim 7:9cd16581b578 285 if (level != NormalLevel) {
IanBenzMaxim 8:5ea891c7d1a1 286 return InvalidLevelError;
IanBenzMaxim 7:9cd16581b578 287 }
IanBenzMaxim 7:9cd16581b578 288
IanBenzMaxim 7:9cd16581b578 289 uint_least8_t packet[3];
IanBenzMaxim 7:9cd16581b578 290 int packetLen = 0;
IanBenzMaxim 7:9cd16581b578 291
IanBenzMaxim 7:9cd16581b578 292 // Check for correct mode.
IanBenzMaxim 7:9cd16581b578 293 if (mode != MODSEL_COMMAND) {
IanBenzMaxim 7:9cd16581b578 294 mode = MODSEL_COMMAND;
IanBenzMaxim 7:9cd16581b578 295 packet[packetLen++] = MODE_COMMAND;
IanBenzMaxim 7:9cd16581b578 296 }
IanBenzMaxim 7:9cd16581b578 297
IanBenzMaxim 7:9cd16581b578 298 // Construct the command.
IanBenzMaxim 8:5ea891c7d1a1 299 packet[packetLen++] =
IanBenzMaxim 8:5ea891c7d1a1 300 CMD_COMM | FUNCTSEL_BIT | (sendBit ? BITPOL_ONE : BITPOL_ZERO) | speed;
IanBenzMaxim 7:9cd16581b578 301 switch (afterLevel) {
IanBenzMaxim 7:9cd16581b578 302 case NormalLevel:
IanBenzMaxim 7:9cd16581b578 303 break;
IanBenzMaxim 7:9cd16581b578 304
IanBenzMaxim 7:9cd16581b578 305 case StrongLevel:
IanBenzMaxim 7:9cd16581b578 306 // Add the command to begin the pulse.
IanBenzMaxim 7:9cd16581b578 307 packet[packetLen++] =
IanBenzMaxim 7:9cd16581b578 308 CMD_COMM | FUNCTSEL_CHMOD | SPEEDSEL_PULSE | BITPOL_5V | PRIME5V_FALSE;
IanBenzMaxim 7:9cd16581b578 309 break;
IanBenzMaxim 7:9cd16581b578 310
IanBenzMaxim 7:9cd16581b578 311 default:
IanBenzMaxim 8:5ea891c7d1a1 312 return InvalidLevelError;
IanBenzMaxim 7:9cd16581b578 313 }
IanBenzMaxim 7:9cd16581b578 314
IanBenzMaxim 7:9cd16581b578 315 // Send the packet.
IanBenzMaxim 8:5ea891c7d1a1 316 TRY(uart->writeBlock(make_span(packet, packetLen)));
IanBenzMaxim 7:9cd16581b578 317
IanBenzMaxim 7:9cd16581b578 318 // Read back the response.
IanBenzMaxim 8:5ea891c7d1a1 319 TRY_VALUE(packet[0], uart->readByte());
IanBenzMaxim 7:9cd16581b578 320
IanBenzMaxim 7:9cd16581b578 321 // Interpret the response.
IanBenzMaxim 8:5ea891c7d1a1 322 if ((packet[0] & 0xE0) != 0x80) {
IanBenzMaxim 8:5ea891c7d1a1 323 return HardwareError;
IanBenzMaxim 7:9cd16581b578 324 }
IanBenzMaxim 8:5ea891c7d1a1 325 level = afterLevel;
IanBenzMaxim 8:5ea891c7d1a1 326 return (packet[0] & RB_BIT_MASK) == RB_BIT_ONE;
IanBenzMaxim 7:9cd16581b578 327 }
IanBenzMaxim 7:9cd16581b578 328
IanBenzMaxim 8:5ea891c7d1a1 329 Result<void> DS2480B::writeByteSetLevel(uint_least8_t sendByte,
IanBenzMaxim 8:5ea891c7d1a1 330 Level afterLevel) {
IanBenzMaxim 7:9cd16581b578 331 if (level != NormalLevel) {
IanBenzMaxim 8:5ea891c7d1a1 332 return InvalidLevelError;
IanBenzMaxim 7:9cd16581b578 333 }
IanBenzMaxim 7:9cd16581b578 334
IanBenzMaxim 7:9cd16581b578 335 switch (afterLevel) {
IanBenzMaxim 7:9cd16581b578 336 case NormalLevel:
IanBenzMaxim 7:9cd16581b578 337 break;
IanBenzMaxim 7:9cd16581b578 338
IanBenzMaxim 7:9cd16581b578 339 case StrongLevel:
IanBenzMaxim 7:9cd16581b578 340 return OneWireMaster::writeByteSetLevel(sendByte, afterLevel);
IanBenzMaxim 7:9cd16581b578 341
IanBenzMaxim 7:9cd16581b578 342 default:
IanBenzMaxim 8:5ea891c7d1a1 343 return InvalidLevelError;
IanBenzMaxim 7:9cd16581b578 344 }
IanBenzMaxim 7:9cd16581b578 345
IanBenzMaxim 7:9cd16581b578 346 uint_least8_t packet[3];
IanBenzMaxim 7:9cd16581b578 347 int packetLen = 0;
IanBenzMaxim 7:9cd16581b578 348
IanBenzMaxim 7:9cd16581b578 349 // Check for correct mode.
IanBenzMaxim 7:9cd16581b578 350 if (mode != MODSEL_DATA) {
IanBenzMaxim 7:9cd16581b578 351 mode = MODSEL_DATA;
IanBenzMaxim 7:9cd16581b578 352 packet[packetLen++] = MODE_DATA;
IanBenzMaxim 7:9cd16581b578 353 }
IanBenzMaxim 7:9cd16581b578 354
IanBenzMaxim 7:9cd16581b578 355 // Add the byte to send.
IanBenzMaxim 7:9cd16581b578 356 packet[packetLen++] = sendByte;
IanBenzMaxim 7:9cd16581b578 357
IanBenzMaxim 7:9cd16581b578 358 // Check for duplication of data that looks like COMMAND mode.
IanBenzMaxim 7:9cd16581b578 359 if (sendByte == MODE_COMMAND) {
IanBenzMaxim 7:9cd16581b578 360 packet[packetLen++] = sendByte;
IanBenzMaxim 7:9cd16581b578 361 }
IanBenzMaxim 7:9cd16581b578 362
IanBenzMaxim 7:9cd16581b578 363 // Send the packet.
IanBenzMaxim 8:5ea891c7d1a1 364 TRY(uart->writeBlock(make_span(packet, packetLen)));
IanBenzMaxim 7:9cd16581b578 365
IanBenzMaxim 7:9cd16581b578 366 // Read back the response.
IanBenzMaxim 8:5ea891c7d1a1 367 TRY_VALUE(packet[0], uart->readByte());
IanBenzMaxim 7:9cd16581b578 368
IanBenzMaxim 7:9cd16581b578 369 // Interpret the response.
IanBenzMaxim 7:9cd16581b578 370 if (packet[0] != sendByte) {
IanBenzMaxim 8:5ea891c7d1a1 371 return HardwareError;
IanBenzMaxim 7:9cd16581b578 372 }
IanBenzMaxim 8:5ea891c7d1a1 373
IanBenzMaxim 8:5ea891c7d1a1 374 return none;
IanBenzMaxim 7:9cd16581b578 375 }
IanBenzMaxim 7:9cd16581b578 376
IanBenzMaxim 8:5ea891c7d1a1 377 Result<uint_least8_t> DS2480B::readByteSetLevel(Level afterLevel) {
IanBenzMaxim 7:9cd16581b578 378 if (level != NormalLevel) {
IanBenzMaxim 8:5ea891c7d1a1 379 return InvalidLevelError;
IanBenzMaxim 7:9cd16581b578 380 }
IanBenzMaxim 7:9cd16581b578 381
IanBenzMaxim 7:9cd16581b578 382 switch (afterLevel) {
IanBenzMaxim 7:9cd16581b578 383 case NormalLevel:
IanBenzMaxim 7:9cd16581b578 384 break;
IanBenzMaxim 7:9cd16581b578 385
IanBenzMaxim 7:9cd16581b578 386 case StrongLevel:
IanBenzMaxim 8:5ea891c7d1a1 387 return OneWireMaster::readByteSetLevel(afterLevel);
IanBenzMaxim 7:9cd16581b578 388
IanBenzMaxim 7:9cd16581b578 389 default:
IanBenzMaxim 8:5ea891c7d1a1 390 return InvalidLevelError;
IanBenzMaxim 7:9cd16581b578 391 }
IanBenzMaxim 7:9cd16581b578 392
IanBenzMaxim 7:9cd16581b578 393 uint_least8_t packet[2];
IanBenzMaxim 7:9cd16581b578 394 int packetLen = 0;
IanBenzMaxim 7:9cd16581b578 395
IanBenzMaxim 7:9cd16581b578 396 // Check for correct mode.
IanBenzMaxim 7:9cd16581b578 397 if (mode != MODSEL_DATA) {
IanBenzMaxim 7:9cd16581b578 398 mode = MODSEL_DATA;
IanBenzMaxim 7:9cd16581b578 399 packet[packetLen++] = MODE_DATA;
IanBenzMaxim 7:9cd16581b578 400 }
IanBenzMaxim 7:9cd16581b578 401
IanBenzMaxim 7:9cd16581b578 402 // Add the byte to send.
IanBenzMaxim 7:9cd16581b578 403 packet[packetLen++] = 0xFF;
IanBenzMaxim 7:9cd16581b578 404
IanBenzMaxim 7:9cd16581b578 405 // Send the packet.
IanBenzMaxim 8:5ea891c7d1a1 406 const Result<void> result = uart->writeBlock(make_span(packet, packetLen));
IanBenzMaxim 8:5ea891c7d1a1 407 if (!result) {
IanBenzMaxim 8:5ea891c7d1a1 408 return result.error();
IanBenzMaxim 7:9cd16581b578 409 }
IanBenzMaxim 7:9cd16581b578 410
IanBenzMaxim 7:9cd16581b578 411 // Read back the response.
IanBenzMaxim 8:5ea891c7d1a1 412 return uart->readByte();
IanBenzMaxim 7:9cd16581b578 413 }
IanBenzMaxim 7:9cd16581b578 414
IanBenzMaxim 8:5ea891c7d1a1 415 Result<void> DS2480B::setSpeed(Speed newSpeed) {
IanBenzMaxim 7:9cd16581b578 416 uint_least8_t newSpeedByte;
IanBenzMaxim 7:9cd16581b578 417 switch (newSpeed) {
IanBenzMaxim 7:9cd16581b578 418 case OverdriveSpeed:
IanBenzMaxim 7:9cd16581b578 419 newSpeedByte = SPEEDSEL_OD;
IanBenzMaxim 7:9cd16581b578 420 break;
IanBenzMaxim 7:9cd16581b578 421
IanBenzMaxim 7:9cd16581b578 422 case StandardSpeed:
IanBenzMaxim 7:9cd16581b578 423 newSpeedByte = SPEEDSEL_STD;
IanBenzMaxim 7:9cd16581b578 424 break;
IanBenzMaxim 7:9cd16581b578 425
IanBenzMaxim 7:9cd16581b578 426 default:
IanBenzMaxim 8:5ea891c7d1a1 427 return InvalidSpeedError;
IanBenzMaxim 7:9cd16581b578 428 }
IanBenzMaxim 7:9cd16581b578 429 if (speed == newSpeedByte) {
IanBenzMaxim 8:5ea891c7d1a1 430 return none;
IanBenzMaxim 7:9cd16581b578 431 }
IanBenzMaxim 7:9cd16581b578 432 speed = newSpeedByte;
IanBenzMaxim 7:9cd16581b578 433
IanBenzMaxim 7:9cd16581b578 434 uint_least8_t packet[2];
IanBenzMaxim 7:9cd16581b578 435 int packetLen = 0;
IanBenzMaxim 7:9cd16581b578 436
IanBenzMaxim 7:9cd16581b578 437 // Check for correct mode.
IanBenzMaxim 7:9cd16581b578 438 if (mode != MODSEL_COMMAND) {
IanBenzMaxim 7:9cd16581b578 439 mode = MODSEL_COMMAND;
IanBenzMaxim 7:9cd16581b578 440 packet[packetLen++] = MODE_COMMAND;
IanBenzMaxim 7:9cd16581b578 441 }
IanBenzMaxim 7:9cd16581b578 442
IanBenzMaxim 7:9cd16581b578 443 // Change DS2480 speed.
IanBenzMaxim 7:9cd16581b578 444 packet[packetLen++] = CMD_COMM | FUNCTSEL_SEARCHOFF | speed;
IanBenzMaxim 7:9cd16581b578 445
IanBenzMaxim 7:9cd16581b578 446 // Send the packet.
IanBenzMaxim 7:9cd16581b578 447 return uart->writeBlock(make_span(packet, packetLen));
IanBenzMaxim 7:9cd16581b578 448 }
IanBenzMaxim 7:9cd16581b578 449
IanBenzMaxim 8:5ea891c7d1a1 450 Result<void> DS2480B::setLevel(Level newLevel) {
IanBenzMaxim 7:9cd16581b578 451 if (level == newLevel) {
IanBenzMaxim 8:5ea891c7d1a1 452 return none;
IanBenzMaxim 7:9cd16581b578 453 }
IanBenzMaxim 7:9cd16581b578 454
IanBenzMaxim 7:9cd16581b578 455 uint_least8_t packet[2];
IanBenzMaxim 7:9cd16581b578 456 int packetLen = 0;
IanBenzMaxim 7:9cd16581b578 457
IanBenzMaxim 7:9cd16581b578 458 switch (newLevel) {
IanBenzMaxim 7:9cd16581b578 459 case NormalLevel:
IanBenzMaxim 7:9cd16581b578 460 // Stop pulse command.
IanBenzMaxim 7:9cd16581b578 461 packet[packetLen++] = MODE_STOP_PULSE;
IanBenzMaxim 7:9cd16581b578 462 break;
IanBenzMaxim 7:9cd16581b578 463
IanBenzMaxim 7:9cd16581b578 464 case StrongLevel:
IanBenzMaxim 7:9cd16581b578 465 // Check for correct mode.
IanBenzMaxim 7:9cd16581b578 466 if (mode != MODSEL_COMMAND) {
IanBenzMaxim 7:9cd16581b578 467 mode = MODSEL_COMMAND;
IanBenzMaxim 7:9cd16581b578 468 packet[packetLen++] = MODE_COMMAND;
IanBenzMaxim 7:9cd16581b578 469 }
IanBenzMaxim 7:9cd16581b578 470
IanBenzMaxim 7:9cd16581b578 471 // Add the command to begin the pulse.
IanBenzMaxim 7:9cd16581b578 472 packet[packetLen++] =
IanBenzMaxim 7:9cd16581b578 473 CMD_COMM | FUNCTSEL_CHMOD | SPEEDSEL_PULSE | BITPOL_5V | PRIME5V_FALSE;
IanBenzMaxim 7:9cd16581b578 474 break;
IanBenzMaxim 7:9cd16581b578 475
IanBenzMaxim 7:9cd16581b578 476 default:
IanBenzMaxim 8:5ea891c7d1a1 477 return InvalidLevelError;
IanBenzMaxim 7:9cd16581b578 478 }
IanBenzMaxim 7:9cd16581b578 479
IanBenzMaxim 7:9cd16581b578 480 // Send the packet.
IanBenzMaxim 8:5ea891c7d1a1 481 TRY(uart->writeBlock(make_span(packet, packetLen)));
IanBenzMaxim 7:9cd16581b578 482
IanBenzMaxim 7:9cd16581b578 483 if (newLevel == NormalLevel) {
IanBenzMaxim 7:9cd16581b578 484 // Read back the response.
IanBenzMaxim 8:5ea891c7d1a1 485 TRY_VALUE(packet[0], uart->readByte());
IanBenzMaxim 7:9cd16581b578 486
IanBenzMaxim 7:9cd16581b578 487 // Interpret the response.
IanBenzMaxim 7:9cd16581b578 488 if ((packet[0] & 0xE0) != 0xE0) {
IanBenzMaxim 8:5ea891c7d1a1 489 return HardwareError;
IanBenzMaxim 7:9cd16581b578 490 }
IanBenzMaxim 7:9cd16581b578 491 }
IanBenzMaxim 7:9cd16581b578 492
IanBenzMaxim 7:9cd16581b578 493 level = newLevel;
IanBenzMaxim 8:5ea891c7d1a1 494 return none;
IanBenzMaxim 7:9cd16581b578 495 }
IanBenzMaxim 7:9cd16581b578 496
IanBenzMaxim 8:5ea891c7d1a1 497 Result<void> DS2480B::sendCommand(uint_least8_t command) {
IanBenzMaxim 7:9cd16581b578 498 uint_least8_t packet[2];
IanBenzMaxim 7:9cd16581b578 499 int packetLen = 0;
IanBenzMaxim 7:9cd16581b578 500
IanBenzMaxim 7:9cd16581b578 501 // Check for correct mode.
IanBenzMaxim 7:9cd16581b578 502 if (mode != MODSEL_COMMAND) {
IanBenzMaxim 7:9cd16581b578 503 mode = MODSEL_COMMAND;
IanBenzMaxim 7:9cd16581b578 504 packet[packetLen++] = MODE_COMMAND;
IanBenzMaxim 7:9cd16581b578 505 }
IanBenzMaxim 7:9cd16581b578 506
IanBenzMaxim 7:9cd16581b578 507 // Add command.
IanBenzMaxim 7:9cd16581b578 508 packet[packetLen++] = command;
IanBenzMaxim 7:9cd16581b578 509
IanBenzMaxim 7:9cd16581b578 510 // Send the packet.
IanBenzMaxim 7:9cd16581b578 511 return uart->writeBlock(make_span(packet, packetLen));
IanBenzMaxim 7:9cd16581b578 512 }
IanBenzMaxim 7:9cd16581b578 513
IanBenzMaxim 7:9cd16581b578 514 const error_category & DS2480B::errorCategory() {
IanBenzMaxim 7:9cd16581b578 515 static class : public error_category {
IanBenzMaxim 7:9cd16581b578 516 public:
IanBenzMaxim 11:3f3bf6bf5e6c 517 virtual const char * name() const {
IanBenzMaxim 11:3f3bf6bf5e6c 518 return "MaximInterfaceDevices.DS2480B";
IanBenzMaxim 11:3f3bf6bf5e6c 519 }
IanBenzMaxim 7:9cd16581b578 520
IanBenzMaxim 7:9cd16581b578 521 virtual std::string message(int condition) const {
IanBenzMaxim 7:9cd16581b578 522 switch (condition) {
IanBenzMaxim 7:9cd16581b578 523 case HardwareError:
IanBenzMaxim 7:9cd16581b578 524 return "Hardware Error";
IanBenzMaxim 7:9cd16581b578 525 }
IanBenzMaxim 8:5ea891c7d1a1 526 return defaultErrorMessage(condition);
IanBenzMaxim 7:9cd16581b578 527 }
IanBenzMaxim 7:9cd16581b578 528 } instance;
IanBenzMaxim 7:9cd16581b578 529 return instance;
IanBenzMaxim 7:9cd16581b578 530 }
IanBenzMaxim 7:9cd16581b578 531
IanBenzMaxim 7:9cd16581b578 532 } // namespace MaximInterfaceDevices