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:
Mon Jul 22 11:44:07 2019 -0500
Revision:
7:9cd16581b578
Child:
8:5ea891c7d1a1
Updated to version 1.9.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
IanBenzMaxim 7:9cd16581b578 1 /*******************************************************************************
IanBenzMaxim 7:9cd16581b578 2 * Copyright (C) 2017 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 7:9cd16581b578 36 // Mode Commands
IanBenzMaxim 7:9cd16581b578 37 #define MODE_DATA 0xE1
IanBenzMaxim 7:9cd16581b578 38 #define MODE_COMMAND 0xE3
IanBenzMaxim 7:9cd16581b578 39 #define MODE_STOP_PULSE 0xF1
IanBenzMaxim 7:9cd16581b578 40
IanBenzMaxim 7:9cd16581b578 41 // Return byte value
IanBenzMaxim 7:9cd16581b578 42 #define RB_CHIPID_MASK 0x1C
IanBenzMaxim 7:9cd16581b578 43 #define RB_RESET_MASK 0x03
IanBenzMaxim 7:9cd16581b578 44 #define RB_1WIRESHORT 0x00
IanBenzMaxim 7:9cd16581b578 45 #define RB_PRESENCE 0x01
IanBenzMaxim 7:9cd16581b578 46 #define RB_ALARMPRESENCE 0x02
IanBenzMaxim 7:9cd16581b578 47 #define RB_NOPRESENCE 0x03
IanBenzMaxim 7:9cd16581b578 48
IanBenzMaxim 7:9cd16581b578 49 #define RB_BIT_MASK 0x03
IanBenzMaxim 7:9cd16581b578 50 #define RB_BIT_ONE 0x03
IanBenzMaxim 7:9cd16581b578 51 #define RB_BIT_ZERO 0x00
IanBenzMaxim 7:9cd16581b578 52
IanBenzMaxim 7:9cd16581b578 53 // Masks for all bit ranges
IanBenzMaxim 7:9cd16581b578 54 #define CMD_MASK 0x80
IanBenzMaxim 7:9cd16581b578 55 #define FUNCTSEL_MASK 0x60
IanBenzMaxim 7:9cd16581b578 56 #define BITPOL_MASK 0x10
IanBenzMaxim 7:9cd16581b578 57 #define SPEEDSEL_MASK 0x0C
IanBenzMaxim 7:9cd16581b578 58 #define MODSEL_MASK 0x02
IanBenzMaxim 7:9cd16581b578 59 #define PARMSEL_MASK 0x70
IanBenzMaxim 7:9cd16581b578 60 #define PARMSET_MASK 0x0E
IanBenzMaxim 7:9cd16581b578 61
IanBenzMaxim 7:9cd16581b578 62 // Command or config bit
IanBenzMaxim 7:9cd16581b578 63 #define CMD_COMM 0x81
IanBenzMaxim 7:9cd16581b578 64 #define CMD_CONFIG 0x01
IanBenzMaxim 7:9cd16581b578 65
IanBenzMaxim 7:9cd16581b578 66 // Function select bits
IanBenzMaxim 7:9cd16581b578 67 #define FUNCTSEL_BIT 0x00
IanBenzMaxim 7:9cd16581b578 68 #define FUNCTSEL_SEARCHON 0x30
IanBenzMaxim 7:9cd16581b578 69 #define FUNCTSEL_SEARCHOFF 0x20
IanBenzMaxim 7:9cd16581b578 70 #define FUNCTSEL_RESET 0x40
IanBenzMaxim 7:9cd16581b578 71 #define FUNCTSEL_CHMOD 0x60
IanBenzMaxim 7:9cd16581b578 72
IanBenzMaxim 7:9cd16581b578 73 // Bit polarity/Pulse voltage bits
IanBenzMaxim 7:9cd16581b578 74 #define BITPOL_ONE 0x10
IanBenzMaxim 7:9cd16581b578 75 #define BITPOL_ZERO 0x00
IanBenzMaxim 7:9cd16581b578 76 #define BITPOL_5V 0x00
IanBenzMaxim 7:9cd16581b578 77 #define BITPOL_12V 0x10
IanBenzMaxim 7:9cd16581b578 78
IanBenzMaxim 7:9cd16581b578 79 // One Wire speed bits
IanBenzMaxim 7:9cd16581b578 80 #define SPEEDSEL_STD 0x00
IanBenzMaxim 7:9cd16581b578 81 #define SPEEDSEL_FLEX 0x04
IanBenzMaxim 7:9cd16581b578 82 #define SPEEDSEL_OD 0x08
IanBenzMaxim 7:9cd16581b578 83 #define SPEEDSEL_PULSE 0x0C
IanBenzMaxim 7:9cd16581b578 84
IanBenzMaxim 7:9cd16581b578 85 // Data/Command mode select bits
IanBenzMaxim 7:9cd16581b578 86 #define MODSEL_DATA 0x00
IanBenzMaxim 7:9cd16581b578 87 #define MODSEL_COMMAND 0x02
IanBenzMaxim 7:9cd16581b578 88
IanBenzMaxim 7:9cd16581b578 89 // 5V Follow Pulse select bits
IanBenzMaxim 7:9cd16581b578 90 #define PRIME5V_TRUE 0x02
IanBenzMaxim 7:9cd16581b578 91 #define PRIME5V_FALSE 0x00
IanBenzMaxim 7:9cd16581b578 92
IanBenzMaxim 7:9cd16581b578 93 // Parameter select bits
IanBenzMaxim 7:9cd16581b578 94 #define PARMSEL_PARMREAD 0x00
IanBenzMaxim 7:9cd16581b578 95 #define PARMSEL_SLEW 0x10
IanBenzMaxim 7:9cd16581b578 96 #define PARMSEL_12VPULSE 0x20
IanBenzMaxim 7:9cd16581b578 97 #define PARMSEL_5VPULSE 0x30
IanBenzMaxim 7:9cd16581b578 98 #define PARMSEL_WRITE1LOW 0x40
IanBenzMaxim 7:9cd16581b578 99 #define PARMSEL_SAMPLEOFFSET 0x50
IanBenzMaxim 7:9cd16581b578 100 #define PARMSEL_ACTIVEPULLUPTIME 0x60
IanBenzMaxim 7:9cd16581b578 101 #define PARMSEL_BAUDRATE 0x70
IanBenzMaxim 7:9cd16581b578 102
IanBenzMaxim 7:9cd16581b578 103 // Pull down slew rate.
IanBenzMaxim 7:9cd16581b578 104 #define PARMSET_Slew15Vus 0x00
IanBenzMaxim 7:9cd16581b578 105 #define PARMSET_Slew2p2Vus 0x02
IanBenzMaxim 7:9cd16581b578 106 #define PARMSET_Slew1p65Vus 0x04
IanBenzMaxim 7:9cd16581b578 107 #define PARMSET_Slew1p37Vus 0x06
IanBenzMaxim 7:9cd16581b578 108 #define PARMSET_Slew1p1Vus 0x08
IanBenzMaxim 7:9cd16581b578 109 #define PARMSET_Slew0p83Vus 0x0A
IanBenzMaxim 7:9cd16581b578 110 #define PARMSET_Slew0p7Vus 0x0C
IanBenzMaxim 7:9cd16581b578 111 #define PARMSET_Slew0p55Vus 0x0E
IanBenzMaxim 7:9cd16581b578 112
IanBenzMaxim 7:9cd16581b578 113 // 12V programming pulse time table
IanBenzMaxim 7:9cd16581b578 114 #define PARMSET_32us 0x00
IanBenzMaxim 7:9cd16581b578 115 #define PARMSET_64us 0x02
IanBenzMaxim 7:9cd16581b578 116 #define PARMSET_128us 0x04
IanBenzMaxim 7:9cd16581b578 117 #define PARMSET_256us 0x06
IanBenzMaxim 7:9cd16581b578 118 #define PARMSET_512us 0x08
IanBenzMaxim 7:9cd16581b578 119 #define PARMSET_1024us 0x0A
IanBenzMaxim 7:9cd16581b578 120 #define PARMSET_2048us 0x0C
IanBenzMaxim 7:9cd16581b578 121 #define PARMSET_infinite 0x0E
IanBenzMaxim 7:9cd16581b578 122
IanBenzMaxim 7:9cd16581b578 123 // 5V strong pull up pulse time table
IanBenzMaxim 7:9cd16581b578 124 #define PARMSET_16p4ms 0x00
IanBenzMaxim 7:9cd16581b578 125 #define PARMSET_65p5ms 0x02
IanBenzMaxim 7:9cd16581b578 126 #define PARMSET_131ms 0x04
IanBenzMaxim 7:9cd16581b578 127 #define PARMSET_262ms 0x06
IanBenzMaxim 7:9cd16581b578 128 #define PARMSET_524ms 0x08
IanBenzMaxim 7:9cd16581b578 129 #define PARMSET_1p05s 0x0A
IanBenzMaxim 7:9cd16581b578 130 #define PARMSET_dynamic 0x0C
IanBenzMaxim 7:9cd16581b578 131 #define PARMSET_infinite 0x0E
IanBenzMaxim 7:9cd16581b578 132
IanBenzMaxim 7:9cd16581b578 133 // Write 1 low time
IanBenzMaxim 7:9cd16581b578 134 #define PARMSET_Write8us 0x00
IanBenzMaxim 7:9cd16581b578 135 #define PARMSET_Write9us 0x02
IanBenzMaxim 7:9cd16581b578 136 #define PARMSET_Write10us 0x04
IanBenzMaxim 7:9cd16581b578 137 #define PARMSET_Write11us 0x06
IanBenzMaxim 7:9cd16581b578 138 #define PARMSET_Write12us 0x08
IanBenzMaxim 7:9cd16581b578 139 #define PARMSET_Write13us 0x0A
IanBenzMaxim 7:9cd16581b578 140 #define PARMSET_Write14us 0x0C
IanBenzMaxim 7:9cd16581b578 141 #define PARMSET_Write15us 0x0E
IanBenzMaxim 7:9cd16581b578 142
IanBenzMaxim 7:9cd16581b578 143 // Data sample offset and Write 0 recovery time
IanBenzMaxim 7:9cd16581b578 144 #define PARMSET_SampOff3us 0x00
IanBenzMaxim 7:9cd16581b578 145 #define PARMSET_SampOff4us 0x02
IanBenzMaxim 7:9cd16581b578 146 #define PARMSET_SampOff5us 0x04
IanBenzMaxim 7:9cd16581b578 147 #define PARMSET_SampOff6us 0x06
IanBenzMaxim 7:9cd16581b578 148 #define PARMSET_SampOff7us 0x08
IanBenzMaxim 7:9cd16581b578 149 #define PARMSET_SampOff8us 0x0A
IanBenzMaxim 7:9cd16581b578 150 #define PARMSET_SampOff9us 0x0C
IanBenzMaxim 7:9cd16581b578 151 #define PARMSET_SampOff10us 0x0E
IanBenzMaxim 7:9cd16581b578 152
IanBenzMaxim 7:9cd16581b578 153 // Active pull up on time
IanBenzMaxim 7:9cd16581b578 154 #define PARMSET_PullUp0p0us 0x00
IanBenzMaxim 7:9cd16581b578 155 #define PARMSET_PullUp0p5us 0x02
IanBenzMaxim 7:9cd16581b578 156 #define PARMSET_PullUp1p0us 0x04
IanBenzMaxim 7:9cd16581b578 157 #define PARMSET_PullUp1p5us 0x06
IanBenzMaxim 7:9cd16581b578 158 #define PARMSET_PullUp2p0us 0x08
IanBenzMaxim 7:9cd16581b578 159 #define PARMSET_PullUp2p5us 0x0A
IanBenzMaxim 7:9cd16581b578 160 #define PARMSET_PullUp3p0us 0x0C
IanBenzMaxim 7:9cd16581b578 161 #define PARMSET_PullUp3p5us 0x0E
IanBenzMaxim 7:9cd16581b578 162
IanBenzMaxim 7:9cd16581b578 163 // Baud rate bits
IanBenzMaxim 7:9cd16581b578 164 #define PARMSET_9600 0x00
IanBenzMaxim 7:9cd16581b578 165 #define PARMSET_19200 0x02
IanBenzMaxim 7:9cd16581b578 166 #define PARMSET_57600 0x04
IanBenzMaxim 7:9cd16581b578 167 #define PARMSET_115200 0x06
IanBenzMaxim 7:9cd16581b578 168
IanBenzMaxim 7:9cd16581b578 169 // DS2480B program voltage available
IanBenzMaxim 7:9cd16581b578 170 #define DS2480BPROG_MASK 0x20
IanBenzMaxim 7:9cd16581b578 171
IanBenzMaxim 7:9cd16581b578 172 namespace MaximInterfaceDevices {
IanBenzMaxim 7:9cd16581b578 173
IanBenzMaxim 7:9cd16581b578 174 using namespace Core;
IanBenzMaxim 7:9cd16581b578 175
IanBenzMaxim 7:9cd16581b578 176 error_code DS2480B::initialize() {
IanBenzMaxim 7:9cd16581b578 177 level = NormalLevel;
IanBenzMaxim 7:9cd16581b578 178 mode = MODSEL_COMMAND;
IanBenzMaxim 7:9cd16581b578 179 speed = SPEEDSEL_STD;
IanBenzMaxim 7:9cd16581b578 180
IanBenzMaxim 7:9cd16581b578 181 // Send a break to reset the DS2480B.
IanBenzMaxim 7:9cd16581b578 182 // Switch to lower baud rate to ensure break is longer than 2 ms.
IanBenzMaxim 7:9cd16581b578 183 error_code result = uart->setBaudRate(4800);
IanBenzMaxim 7:9cd16581b578 184 if (result) {
IanBenzMaxim 7:9cd16581b578 185 return result;
IanBenzMaxim 7:9cd16581b578 186 }
IanBenzMaxim 7:9cd16581b578 187 result = uart->sendBreak();
IanBenzMaxim 7:9cd16581b578 188 if (result) {
IanBenzMaxim 7:9cd16581b578 189 return result;
IanBenzMaxim 7:9cd16581b578 190 }
IanBenzMaxim 7:9cd16581b578 191 result = uart->setBaudRate(9600);
IanBenzMaxim 7:9cd16581b578 192 if (result) {
IanBenzMaxim 7:9cd16581b578 193 return result;
IanBenzMaxim 7:9cd16581b578 194 }
IanBenzMaxim 7:9cd16581b578 195
IanBenzMaxim 7:9cd16581b578 196 // Wait for master reset.
IanBenzMaxim 7:9cd16581b578 197 sleep->invoke(1);
IanBenzMaxim 7:9cd16581b578 198
IanBenzMaxim 7:9cd16581b578 199 // Flush the read buffer.
IanBenzMaxim 7:9cd16581b578 200 result = uart->clearReadBuffer();
IanBenzMaxim 7:9cd16581b578 201 if (result) {
IanBenzMaxim 7:9cd16581b578 202 return result;
IanBenzMaxim 7:9cd16581b578 203 }
IanBenzMaxim 7:9cd16581b578 204
IanBenzMaxim 7:9cd16581b578 205 // Send the timing byte.
IanBenzMaxim 7:9cd16581b578 206 result = uart->writeByte(CMD_COMM | FUNCTSEL_RESET | SPEEDSEL_STD);
IanBenzMaxim 7:9cd16581b578 207 if (result) {
IanBenzMaxim 7:9cd16581b578 208 return result;
IanBenzMaxim 7:9cd16581b578 209 }
IanBenzMaxim 7:9cd16581b578 210
IanBenzMaxim 7:9cd16581b578 211 // Change the DS2480 baud rate.
IanBenzMaxim 7:9cd16581b578 212 result = uart->writeByte(CMD_CONFIG | PARMSEL_BAUDRATE | PARMSET_115200);
IanBenzMaxim 7:9cd16581b578 213 if (result) {
IanBenzMaxim 7:9cd16581b578 214 return result;
IanBenzMaxim 7:9cd16581b578 215 }
IanBenzMaxim 7:9cd16581b578 216
IanBenzMaxim 7:9cd16581b578 217 // Change our baud rate.
IanBenzMaxim 7:9cd16581b578 218 result = uart->setBaudRate(115200);
IanBenzMaxim 7:9cd16581b578 219 if (result) {
IanBenzMaxim 7:9cd16581b578 220 return result;
IanBenzMaxim 7:9cd16581b578 221 }
IanBenzMaxim 7:9cd16581b578 222
IanBenzMaxim 7:9cd16581b578 223 uint_least8_t response;
IanBenzMaxim 7:9cd16581b578 224
IanBenzMaxim 7:9cd16581b578 225 // Verify response.
IanBenzMaxim 7:9cd16581b578 226 result = uart->readByte(response);
IanBenzMaxim 7:9cd16581b578 227 if (result) {
IanBenzMaxim 7:9cd16581b578 228 return result;
IanBenzMaxim 7:9cd16581b578 229 }
IanBenzMaxim 7:9cd16581b578 230 if ((response & (PARMSEL_MASK | PARMSET_MASK)) !=
IanBenzMaxim 7:9cd16581b578 231 (PARMSEL_BAUDRATE | PARMSET_115200)) {
IanBenzMaxim 7:9cd16581b578 232 return make_error_code(HardwareError);
IanBenzMaxim 7:9cd16581b578 233 }
IanBenzMaxim 7:9cd16581b578 234
IanBenzMaxim 7:9cd16581b578 235 // Set the SPUD time value.
IanBenzMaxim 7:9cd16581b578 236 result = uart->writeByte(CMD_CONFIG | PARMSEL_5VPULSE | PARMSET_infinite);
IanBenzMaxim 7:9cd16581b578 237 if (result) {
IanBenzMaxim 7:9cd16581b578 238 return result;
IanBenzMaxim 7:9cd16581b578 239 }
IanBenzMaxim 7:9cd16581b578 240
IanBenzMaxim 7:9cd16581b578 241 // Verify response.
IanBenzMaxim 7:9cd16581b578 242 result = uart->readByte(response);
IanBenzMaxim 7:9cd16581b578 243 if (result) {
IanBenzMaxim 7:9cd16581b578 244 return result;
IanBenzMaxim 7:9cd16581b578 245 }
IanBenzMaxim 7:9cd16581b578 246 if ((response & (PARMSEL_MASK | PARMSET_MASK)) !=
IanBenzMaxim 7:9cd16581b578 247 (PARMSEL_5VPULSE | PARMSET_infinite)) {
IanBenzMaxim 7:9cd16581b578 248 return make_error_code(HardwareError);
IanBenzMaxim 7:9cd16581b578 249 }
IanBenzMaxim 7:9cd16581b578 250
IanBenzMaxim 7:9cd16581b578 251 return result;
IanBenzMaxim 7:9cd16581b578 252 }
IanBenzMaxim 7:9cd16581b578 253
IanBenzMaxim 7:9cd16581b578 254 error_code DS2480B::reset() {
IanBenzMaxim 7:9cd16581b578 255 if (level != NormalLevel) {
IanBenzMaxim 7:9cd16581b578 256 return make_error_code(InvalidLevelError);
IanBenzMaxim 7:9cd16581b578 257 }
IanBenzMaxim 7:9cd16581b578 258
IanBenzMaxim 7:9cd16581b578 259 uint_least8_t packet[2];
IanBenzMaxim 7:9cd16581b578 260 int packetLen = 0;
IanBenzMaxim 7:9cd16581b578 261
IanBenzMaxim 7:9cd16581b578 262 // Check for correct mode.
IanBenzMaxim 7:9cd16581b578 263 if (mode != MODSEL_COMMAND) {
IanBenzMaxim 7:9cd16581b578 264 mode = MODSEL_COMMAND;
IanBenzMaxim 7:9cd16581b578 265 packet[packetLen++] = MODE_COMMAND;
IanBenzMaxim 7:9cd16581b578 266 }
IanBenzMaxim 7:9cd16581b578 267
IanBenzMaxim 7:9cd16581b578 268 // Construct the command.
IanBenzMaxim 7:9cd16581b578 269 packet[packetLen++] = CMD_COMM | FUNCTSEL_RESET | speed;
IanBenzMaxim 7:9cd16581b578 270
IanBenzMaxim 7:9cd16581b578 271 // Send the packet.
IanBenzMaxim 7:9cd16581b578 272 error_code result = uart->writeBlock(make_span(packet, packetLen));
IanBenzMaxim 7:9cd16581b578 273 if (result) {
IanBenzMaxim 7:9cd16581b578 274 return result;
IanBenzMaxim 7:9cd16581b578 275 }
IanBenzMaxim 7:9cd16581b578 276
IanBenzMaxim 7:9cd16581b578 277 // Read back the response.
IanBenzMaxim 7:9cd16581b578 278 result = uart->readByte(packet[0]);
IanBenzMaxim 7:9cd16581b578 279 if (result) {
IanBenzMaxim 7:9cd16581b578 280 return result;
IanBenzMaxim 7:9cd16581b578 281 }
IanBenzMaxim 7:9cd16581b578 282
IanBenzMaxim 7:9cd16581b578 283 // Make sure this byte looks like a reset byte.
IanBenzMaxim 7:9cd16581b578 284 if ((packet[0] & RB_RESET_MASK) == RB_1WIRESHORT) {
IanBenzMaxim 7:9cd16581b578 285 result = make_error_code(ShortDetectedError);
IanBenzMaxim 7:9cd16581b578 286 } else if ((packet[0] & RB_RESET_MASK) == RB_NOPRESENCE) {
IanBenzMaxim 7:9cd16581b578 287 result = make_error_code(NoSlaveError);
IanBenzMaxim 7:9cd16581b578 288 }
IanBenzMaxim 7:9cd16581b578 289 return result;
IanBenzMaxim 7:9cd16581b578 290 }
IanBenzMaxim 7:9cd16581b578 291
IanBenzMaxim 7:9cd16581b578 292 error_code DS2480B::touchBitSetLevel(bool & sendRecvBit, Level afterLevel) {
IanBenzMaxim 7:9cd16581b578 293 if (level != NormalLevel) {
IanBenzMaxim 7:9cd16581b578 294 return make_error_code(InvalidLevelError);
IanBenzMaxim 7:9cd16581b578 295 }
IanBenzMaxim 7:9cd16581b578 296
IanBenzMaxim 7:9cd16581b578 297 uint_least8_t packet[3];
IanBenzMaxim 7:9cd16581b578 298 int packetLen = 0;
IanBenzMaxim 7:9cd16581b578 299
IanBenzMaxim 7:9cd16581b578 300 // Check for correct mode.
IanBenzMaxim 7:9cd16581b578 301 if (mode != MODSEL_COMMAND) {
IanBenzMaxim 7:9cd16581b578 302 mode = MODSEL_COMMAND;
IanBenzMaxim 7:9cd16581b578 303 packet[packetLen++] = MODE_COMMAND;
IanBenzMaxim 7:9cd16581b578 304 }
IanBenzMaxim 7:9cd16581b578 305
IanBenzMaxim 7:9cd16581b578 306 // Construct the command.
IanBenzMaxim 7:9cd16581b578 307 packet[packetLen++] = CMD_COMM | FUNCTSEL_BIT |
IanBenzMaxim 7:9cd16581b578 308 (sendRecvBit ? BITPOL_ONE : BITPOL_ZERO) | speed;
IanBenzMaxim 7:9cd16581b578 309 switch (afterLevel) {
IanBenzMaxim 7:9cd16581b578 310 case NormalLevel:
IanBenzMaxim 7:9cd16581b578 311 break;
IanBenzMaxim 7:9cd16581b578 312
IanBenzMaxim 7:9cd16581b578 313 case StrongLevel:
IanBenzMaxim 7:9cd16581b578 314 // Add the command to begin the pulse.
IanBenzMaxim 7:9cd16581b578 315 packet[packetLen++] =
IanBenzMaxim 7:9cd16581b578 316 CMD_COMM | FUNCTSEL_CHMOD | SPEEDSEL_PULSE | BITPOL_5V | PRIME5V_FALSE;
IanBenzMaxim 7:9cd16581b578 317 break;
IanBenzMaxim 7:9cd16581b578 318
IanBenzMaxim 7:9cd16581b578 319 default:
IanBenzMaxim 7:9cd16581b578 320 return make_error_code(InvalidLevelError);
IanBenzMaxim 7:9cd16581b578 321 }
IanBenzMaxim 7:9cd16581b578 322
IanBenzMaxim 7:9cd16581b578 323 // Send the packet.
IanBenzMaxim 7:9cd16581b578 324 error_code result = uart->writeBlock(make_span(packet, packetLen));
IanBenzMaxim 7:9cd16581b578 325 if (result) {
IanBenzMaxim 7:9cd16581b578 326 return result;
IanBenzMaxim 7:9cd16581b578 327 }
IanBenzMaxim 7:9cd16581b578 328
IanBenzMaxim 7:9cd16581b578 329 // Read back the response.
IanBenzMaxim 7:9cd16581b578 330 result = uart->readByte(packet[0]);
IanBenzMaxim 7:9cd16581b578 331 if (result) {
IanBenzMaxim 7:9cd16581b578 332 return result;
IanBenzMaxim 7:9cd16581b578 333 }
IanBenzMaxim 7:9cd16581b578 334
IanBenzMaxim 7:9cd16581b578 335 // Interpret the response.
IanBenzMaxim 7:9cd16581b578 336 if ((packet[0] & 0xE0) == 0x80) {
IanBenzMaxim 7:9cd16581b578 337 sendRecvBit = ((packet[0] & RB_BIT_MASK) == RB_BIT_ONE);
IanBenzMaxim 7:9cd16581b578 338 level = afterLevel;
IanBenzMaxim 7:9cd16581b578 339 } else {
IanBenzMaxim 7:9cd16581b578 340 result = make_error_code(HardwareError);
IanBenzMaxim 7:9cd16581b578 341 }
IanBenzMaxim 7:9cd16581b578 342 return result;
IanBenzMaxim 7:9cd16581b578 343 }
IanBenzMaxim 7:9cd16581b578 344
IanBenzMaxim 7:9cd16581b578 345 error_code DS2480B::writeByteSetLevel(uint_least8_t sendByte,
IanBenzMaxim 7:9cd16581b578 346 Level afterLevel) {
IanBenzMaxim 7:9cd16581b578 347 if (level != NormalLevel) {
IanBenzMaxim 7:9cd16581b578 348 return make_error_code(InvalidLevelError);
IanBenzMaxim 7:9cd16581b578 349 }
IanBenzMaxim 7:9cd16581b578 350
IanBenzMaxim 7:9cd16581b578 351 switch (afterLevel) {
IanBenzMaxim 7:9cd16581b578 352 case NormalLevel:
IanBenzMaxim 7:9cd16581b578 353 break;
IanBenzMaxim 7:9cd16581b578 354
IanBenzMaxim 7:9cd16581b578 355 case StrongLevel:
IanBenzMaxim 7:9cd16581b578 356 return OneWireMaster::writeByteSetLevel(sendByte, afterLevel);
IanBenzMaxim 7:9cd16581b578 357
IanBenzMaxim 7:9cd16581b578 358 default:
IanBenzMaxim 7:9cd16581b578 359 return make_error_code(InvalidLevelError);
IanBenzMaxim 7:9cd16581b578 360 }
IanBenzMaxim 7:9cd16581b578 361
IanBenzMaxim 7:9cd16581b578 362 uint_least8_t packet[3];
IanBenzMaxim 7:9cd16581b578 363 int packetLen = 0;
IanBenzMaxim 7:9cd16581b578 364
IanBenzMaxim 7:9cd16581b578 365 // Check for correct mode.
IanBenzMaxim 7:9cd16581b578 366 if (mode != MODSEL_DATA) {
IanBenzMaxim 7:9cd16581b578 367 mode = MODSEL_DATA;
IanBenzMaxim 7:9cd16581b578 368 packet[packetLen++] = MODE_DATA;
IanBenzMaxim 7:9cd16581b578 369 }
IanBenzMaxim 7:9cd16581b578 370
IanBenzMaxim 7:9cd16581b578 371 // Add the byte to send.
IanBenzMaxim 7:9cd16581b578 372 packet[packetLen++] = sendByte;
IanBenzMaxim 7:9cd16581b578 373
IanBenzMaxim 7:9cd16581b578 374 // Check for duplication of data that looks like COMMAND mode.
IanBenzMaxim 7:9cd16581b578 375 if (sendByte == MODE_COMMAND) {
IanBenzMaxim 7:9cd16581b578 376 packet[packetLen++] = sendByte;
IanBenzMaxim 7:9cd16581b578 377 }
IanBenzMaxim 7:9cd16581b578 378
IanBenzMaxim 7:9cd16581b578 379 // Send the packet.
IanBenzMaxim 7:9cd16581b578 380 error_code result = uart->writeBlock(make_span(packet, packetLen));
IanBenzMaxim 7:9cd16581b578 381 if (result) {
IanBenzMaxim 7:9cd16581b578 382 return result;
IanBenzMaxim 7:9cd16581b578 383 }
IanBenzMaxim 7:9cd16581b578 384
IanBenzMaxim 7:9cd16581b578 385 // Read back the response.
IanBenzMaxim 7:9cd16581b578 386 result = uart->readByte(packet[0]);
IanBenzMaxim 7:9cd16581b578 387 if (result) {
IanBenzMaxim 7:9cd16581b578 388 return result;
IanBenzMaxim 7:9cd16581b578 389 }
IanBenzMaxim 7:9cd16581b578 390
IanBenzMaxim 7:9cd16581b578 391 // Interpret the response.
IanBenzMaxim 7:9cd16581b578 392 if (packet[0] != sendByte) {
IanBenzMaxim 7:9cd16581b578 393 result = make_error_code(HardwareError);
IanBenzMaxim 7:9cd16581b578 394 }
IanBenzMaxim 7:9cd16581b578 395 return result;
IanBenzMaxim 7:9cd16581b578 396 }
IanBenzMaxim 7:9cd16581b578 397
IanBenzMaxim 7:9cd16581b578 398 error_code DS2480B::readByteSetLevel(uint_least8_t & recvByte,
IanBenzMaxim 7:9cd16581b578 399 Level afterLevel) {
IanBenzMaxim 7:9cd16581b578 400 if (level != NormalLevel) {
IanBenzMaxim 7:9cd16581b578 401 return make_error_code(InvalidLevelError);
IanBenzMaxim 7:9cd16581b578 402 }
IanBenzMaxim 7:9cd16581b578 403
IanBenzMaxim 7:9cd16581b578 404 switch (afterLevel) {
IanBenzMaxim 7:9cd16581b578 405 case NormalLevel:
IanBenzMaxim 7:9cd16581b578 406 break;
IanBenzMaxim 7:9cd16581b578 407
IanBenzMaxim 7:9cd16581b578 408 case StrongLevel:
IanBenzMaxim 7:9cd16581b578 409 return OneWireMaster::readByteSetLevel(recvByte, afterLevel);
IanBenzMaxim 7:9cd16581b578 410
IanBenzMaxim 7:9cd16581b578 411 default:
IanBenzMaxim 7:9cd16581b578 412 return make_error_code(InvalidLevelError);
IanBenzMaxim 7:9cd16581b578 413 }
IanBenzMaxim 7:9cd16581b578 414
IanBenzMaxim 7:9cd16581b578 415 uint_least8_t packet[2];
IanBenzMaxim 7:9cd16581b578 416 int packetLen = 0;
IanBenzMaxim 7:9cd16581b578 417
IanBenzMaxim 7:9cd16581b578 418 // Check for correct mode.
IanBenzMaxim 7:9cd16581b578 419 if (mode != MODSEL_DATA) {
IanBenzMaxim 7:9cd16581b578 420 mode = MODSEL_DATA;
IanBenzMaxim 7:9cd16581b578 421 packet[packetLen++] = MODE_DATA;
IanBenzMaxim 7:9cd16581b578 422 }
IanBenzMaxim 7:9cd16581b578 423
IanBenzMaxim 7:9cd16581b578 424 // Add the byte to send.
IanBenzMaxim 7:9cd16581b578 425 packet[packetLen++] = 0xFF;
IanBenzMaxim 7:9cd16581b578 426
IanBenzMaxim 7:9cd16581b578 427 // Send the packet.
IanBenzMaxim 7:9cd16581b578 428 error_code result = uart->writeBlock(make_span(packet, packetLen));
IanBenzMaxim 7:9cd16581b578 429 if (result) {
IanBenzMaxim 7:9cd16581b578 430 return result;
IanBenzMaxim 7:9cd16581b578 431 }
IanBenzMaxim 7:9cd16581b578 432
IanBenzMaxim 7:9cd16581b578 433 // Read back the response.
IanBenzMaxim 7:9cd16581b578 434 result = uart->readByte(recvByte);
IanBenzMaxim 7:9cd16581b578 435 return result;
IanBenzMaxim 7:9cd16581b578 436 }
IanBenzMaxim 7:9cd16581b578 437
IanBenzMaxim 7:9cd16581b578 438 error_code DS2480B::setSpeed(Speed newSpeed) {
IanBenzMaxim 7:9cd16581b578 439 uint_least8_t newSpeedByte;
IanBenzMaxim 7:9cd16581b578 440 switch (newSpeed) {
IanBenzMaxim 7:9cd16581b578 441 case OverdriveSpeed:
IanBenzMaxim 7:9cd16581b578 442 newSpeedByte = SPEEDSEL_OD;
IanBenzMaxim 7:9cd16581b578 443 break;
IanBenzMaxim 7:9cd16581b578 444
IanBenzMaxim 7:9cd16581b578 445 case StandardSpeed:
IanBenzMaxim 7:9cd16581b578 446 newSpeedByte = SPEEDSEL_STD;
IanBenzMaxim 7:9cd16581b578 447 break;
IanBenzMaxim 7:9cd16581b578 448
IanBenzMaxim 7:9cd16581b578 449 default:
IanBenzMaxim 7:9cd16581b578 450 return make_error_code(InvalidSpeedError);
IanBenzMaxim 7:9cd16581b578 451 }
IanBenzMaxim 7:9cd16581b578 452 if (speed == newSpeedByte) {
IanBenzMaxim 7:9cd16581b578 453 return error_code();
IanBenzMaxim 7:9cd16581b578 454 }
IanBenzMaxim 7:9cd16581b578 455 speed = newSpeedByte;
IanBenzMaxim 7:9cd16581b578 456
IanBenzMaxim 7:9cd16581b578 457 uint_least8_t packet[2];
IanBenzMaxim 7:9cd16581b578 458 int packetLen = 0;
IanBenzMaxim 7:9cd16581b578 459
IanBenzMaxim 7:9cd16581b578 460 // Check for correct mode.
IanBenzMaxim 7:9cd16581b578 461 if (mode != MODSEL_COMMAND) {
IanBenzMaxim 7:9cd16581b578 462 mode = MODSEL_COMMAND;
IanBenzMaxim 7:9cd16581b578 463 packet[packetLen++] = MODE_COMMAND;
IanBenzMaxim 7:9cd16581b578 464 }
IanBenzMaxim 7:9cd16581b578 465
IanBenzMaxim 7:9cd16581b578 466 // Change DS2480 speed.
IanBenzMaxim 7:9cd16581b578 467 packet[packetLen++] = CMD_COMM | FUNCTSEL_SEARCHOFF | speed;
IanBenzMaxim 7:9cd16581b578 468
IanBenzMaxim 7:9cd16581b578 469 // Send the packet.
IanBenzMaxim 7:9cd16581b578 470 return uart->writeBlock(make_span(packet, packetLen));
IanBenzMaxim 7:9cd16581b578 471 }
IanBenzMaxim 7:9cd16581b578 472
IanBenzMaxim 7:9cd16581b578 473 error_code DS2480B::setLevel(Level newLevel) {
IanBenzMaxim 7:9cd16581b578 474 if (level == newLevel) {
IanBenzMaxim 7:9cd16581b578 475 return error_code();
IanBenzMaxim 7:9cd16581b578 476 }
IanBenzMaxim 7:9cd16581b578 477
IanBenzMaxim 7:9cd16581b578 478 uint_least8_t packet[2];
IanBenzMaxim 7:9cd16581b578 479 int packetLen = 0;
IanBenzMaxim 7:9cd16581b578 480
IanBenzMaxim 7:9cd16581b578 481 switch (newLevel) {
IanBenzMaxim 7:9cd16581b578 482 case NormalLevel:
IanBenzMaxim 7:9cd16581b578 483 // Stop pulse command.
IanBenzMaxim 7:9cd16581b578 484 packet[packetLen++] = MODE_STOP_PULSE;
IanBenzMaxim 7:9cd16581b578 485 break;
IanBenzMaxim 7:9cd16581b578 486
IanBenzMaxim 7:9cd16581b578 487 case StrongLevel:
IanBenzMaxim 7:9cd16581b578 488 // Check for correct mode.
IanBenzMaxim 7:9cd16581b578 489 if (mode != MODSEL_COMMAND) {
IanBenzMaxim 7:9cd16581b578 490 mode = MODSEL_COMMAND;
IanBenzMaxim 7:9cd16581b578 491 packet[packetLen++] = MODE_COMMAND;
IanBenzMaxim 7:9cd16581b578 492 }
IanBenzMaxim 7:9cd16581b578 493
IanBenzMaxim 7:9cd16581b578 494 // Add the command to begin the pulse.
IanBenzMaxim 7:9cd16581b578 495 packet[packetLen++] =
IanBenzMaxim 7:9cd16581b578 496 CMD_COMM | FUNCTSEL_CHMOD | SPEEDSEL_PULSE | BITPOL_5V | PRIME5V_FALSE;
IanBenzMaxim 7:9cd16581b578 497 break;
IanBenzMaxim 7:9cd16581b578 498
IanBenzMaxim 7:9cd16581b578 499 default:
IanBenzMaxim 7:9cd16581b578 500 return make_error_code(InvalidLevelError);
IanBenzMaxim 7:9cd16581b578 501 }
IanBenzMaxim 7:9cd16581b578 502
IanBenzMaxim 7:9cd16581b578 503 // Send the packet.
IanBenzMaxim 7:9cd16581b578 504 error_code result = uart->writeBlock(make_span(packet, packetLen));
IanBenzMaxim 7:9cd16581b578 505 if (result) {
IanBenzMaxim 7:9cd16581b578 506 return result;
IanBenzMaxim 7:9cd16581b578 507 }
IanBenzMaxim 7:9cd16581b578 508
IanBenzMaxim 7:9cd16581b578 509 if (newLevel == NormalLevel) {
IanBenzMaxim 7:9cd16581b578 510 // Read back the response.
IanBenzMaxim 7:9cd16581b578 511 result = uart->readByte(packet[0]);
IanBenzMaxim 7:9cd16581b578 512 if (result) {
IanBenzMaxim 7:9cd16581b578 513 return result;
IanBenzMaxim 7:9cd16581b578 514 }
IanBenzMaxim 7:9cd16581b578 515
IanBenzMaxim 7:9cd16581b578 516 // Interpret the response.
IanBenzMaxim 7:9cd16581b578 517 if ((packet[0] & 0xE0) != 0xE0) {
IanBenzMaxim 7:9cd16581b578 518 return make_error_code(HardwareError);
IanBenzMaxim 7:9cd16581b578 519 }
IanBenzMaxim 7:9cd16581b578 520 }
IanBenzMaxim 7:9cd16581b578 521
IanBenzMaxim 7:9cd16581b578 522 level = newLevel;
IanBenzMaxim 7:9cd16581b578 523 return result;
IanBenzMaxim 7:9cd16581b578 524 }
IanBenzMaxim 7:9cd16581b578 525
IanBenzMaxim 7:9cd16581b578 526 error_code DS2480B::sendCommand(uint_least8_t command) {
IanBenzMaxim 7:9cd16581b578 527 uint_least8_t packet[2];
IanBenzMaxim 7:9cd16581b578 528 int packetLen = 0;
IanBenzMaxim 7:9cd16581b578 529
IanBenzMaxim 7:9cd16581b578 530 // Check for correct mode.
IanBenzMaxim 7:9cd16581b578 531 if (mode != MODSEL_COMMAND) {
IanBenzMaxim 7:9cd16581b578 532 mode = MODSEL_COMMAND;
IanBenzMaxim 7:9cd16581b578 533 packet[packetLen++] = MODE_COMMAND;
IanBenzMaxim 7:9cd16581b578 534 }
IanBenzMaxim 7:9cd16581b578 535
IanBenzMaxim 7:9cd16581b578 536 // Add command.
IanBenzMaxim 7:9cd16581b578 537 packet[packetLen++] = command;
IanBenzMaxim 7:9cd16581b578 538
IanBenzMaxim 7:9cd16581b578 539 // Send the packet.
IanBenzMaxim 7:9cd16581b578 540 return uart->writeBlock(make_span(packet, packetLen));
IanBenzMaxim 7:9cd16581b578 541 }
IanBenzMaxim 7:9cd16581b578 542
IanBenzMaxim 7:9cd16581b578 543 const error_category & DS2480B::errorCategory() {
IanBenzMaxim 7:9cd16581b578 544 static class : public error_category {
IanBenzMaxim 7:9cd16581b578 545 public:
IanBenzMaxim 7:9cd16581b578 546 virtual const char * name() const { return "DS2480B"; }
IanBenzMaxim 7:9cd16581b578 547
IanBenzMaxim 7:9cd16581b578 548 virtual std::string message(int condition) const {
IanBenzMaxim 7:9cd16581b578 549 switch (condition) {
IanBenzMaxim 7:9cd16581b578 550 case HardwareError:
IanBenzMaxim 7:9cd16581b578 551 return "Hardware Error";
IanBenzMaxim 7:9cd16581b578 552
IanBenzMaxim 7:9cd16581b578 553 default:
IanBenzMaxim 7:9cd16581b578 554 return defaultErrorMessage(condition);
IanBenzMaxim 7:9cd16581b578 555 }
IanBenzMaxim 7:9cd16581b578 556 }
IanBenzMaxim 7:9cd16581b578 557 } instance;
IanBenzMaxim 7:9cd16581b578 558 return instance;
IanBenzMaxim 7:9cd16581b578 559 }
IanBenzMaxim 7:9cd16581b578 560
IanBenzMaxim 7:9cd16581b578 561 } // namespace MaximInterfaceDevices