Extended MaximInterface

Dependents:   mbed_DS28EC20_GPIO

Committer:
reARMnimator
Date:
Mon Jan 06 15:54:55 2020 +0000
Revision:
10:de4b8812877d
Parent:
9:aeda90624ad0
Fixed inappropriate include path.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
reARMnimator 9:aeda90624ad0 1 /*******************************************************************************
reARMnimator 9:aeda90624ad0 2 * Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved.
reARMnimator 9:aeda90624ad0 3 *
reARMnimator 9:aeda90624ad0 4 * Permission is hereby granted, free of charge, to any person obtaining a
reARMnimator 9:aeda90624ad0 5 * copy of this software and associated documentation files (the "Software"),
reARMnimator 9:aeda90624ad0 6 * to deal in the Software without restriction, including without limitation
reARMnimator 9:aeda90624ad0 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
reARMnimator 9:aeda90624ad0 8 * and/or sell copies of the Software, and to permit persons to whom the
reARMnimator 9:aeda90624ad0 9 * Software is furnished to do so, subject to the following conditions:
reARMnimator 9:aeda90624ad0 10 *
reARMnimator 9:aeda90624ad0 11 * The above copyright notice and this permission notice shall be included
reARMnimator 9:aeda90624ad0 12 * in all copies or substantial portions of the Software.
reARMnimator 9:aeda90624ad0 13 *
reARMnimator 9:aeda90624ad0 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
reARMnimator 9:aeda90624ad0 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
reARMnimator 9:aeda90624ad0 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
reARMnimator 9:aeda90624ad0 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
reARMnimator 9:aeda90624ad0 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
reARMnimator 9:aeda90624ad0 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
reARMnimator 9:aeda90624ad0 20 * OTHER DEALINGS IN THE SOFTWARE.
reARMnimator 9:aeda90624ad0 21 *
reARMnimator 9:aeda90624ad0 22 * Except as contained in this notice, the name of Maxim Integrated
reARMnimator 9:aeda90624ad0 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
reARMnimator 9:aeda90624ad0 24 * Products, Inc. Branding Policy.
reARMnimator 9:aeda90624ad0 25 *
reARMnimator 9:aeda90624ad0 26 * The mere transfer of this software does not imply any licenses
reARMnimator 9:aeda90624ad0 27 * of trade secrets, proprietary technology, copyrights, patents,
reARMnimator 9:aeda90624ad0 28 * trademarks, maskwork rights, or any other form of intellectual
reARMnimator 9:aeda90624ad0 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
reARMnimator 9:aeda90624ad0 30 * ownership rights.
reARMnimator 9:aeda90624ad0 31 *******************************************************************************/
reARMnimator 9:aeda90624ad0 32
reARMnimator 9:aeda90624ad0 33 #include "DS28EC20.hpp"
reARMnimator 9:aeda90624ad0 34 #include <MaximInterface/Links/OneWireMaster.hpp>
reARMnimator 9:aeda90624ad0 35 #include <MaximInterface/Utilities/Error.hpp>
reARMnimator 9:aeda90624ad0 36 #include <MaximInterface/Utilities/crc.hpp>
reARMnimator 9:aeda90624ad0 37
reARMnimator 9:aeda90624ad0 38 #include <algorithm>
reARMnimator 9:aeda90624ad0 39 #include <string.h>
reARMnimator 9:aeda90624ad0 40
reARMnimator 9:aeda90624ad0 41 namespace MaximInterface {
reARMnimator 9:aeda90624ad0 42
reARMnimator 9:aeda90624ad0 43 typedef enum _Command_t
reARMnimator 9:aeda90624ad0 44 {
reARMnimator 9:aeda90624ad0 45 WriteScratchpad = 0x0F,
reARMnimator 9:aeda90624ad0 46 ReadScratchpad = 0xAA,
reARMnimator 9:aeda90624ad0 47 CopyScratchpad = 0x55,
reARMnimator 9:aeda90624ad0 48 ReadMemory = 0xF0,
reARMnimator 9:aeda90624ad0 49 ReadMemoryExt = 0xA5
reARMnimator 9:aeda90624ad0 50 } Command;
reARMnimator 9:aeda90624ad0 51
reARMnimator 9:aeda90624ad0 52
reARMnimator 9:aeda90624ad0 53
reARMnimator 9:aeda90624ad0 54 error_code writeMemory(DS28EC20 & device, DS28EC20::Address targetAddress,
reARMnimator 9:aeda90624ad0 55 const DS28EC20::Scratchpad & data) {
reARMnimator 9:aeda90624ad0 56 error_code result = device.writeScratchpad(targetAddress, data);
reARMnimator 9:aeda90624ad0 57 if (result) {
reARMnimator 9:aeda90624ad0 58 return result;
reARMnimator 9:aeda90624ad0 59 }
reARMnimator 9:aeda90624ad0 60 DS28EC20::Scratchpad readData;
reARMnimator 9:aeda90624ad0 61 uint_least8_t esByte;
reARMnimator 9:aeda90624ad0 62 result = device.readScratchpad(readData, esByte);
reARMnimator 9:aeda90624ad0 63 if (result) {
reARMnimator 9:aeda90624ad0 64 return result;
reARMnimator 9:aeda90624ad0 65 }
reARMnimator 9:aeda90624ad0 66 result = device.copyScratchpad(targetAddress, esByte);
reARMnimator 9:aeda90624ad0 67 return result;
reARMnimator 9:aeda90624ad0 68 }
reARMnimator 9:aeda90624ad0 69
reARMnimator 9:aeda90624ad0 70
reARMnimator 9:aeda90624ad0 71 error_code writeMemory(DS28EC20 & device, DS28EC20::Address inAddress,
reARMnimator 9:aeda90624ad0 72 const uint_least8_t * dataIn, size_t dataLen)
reARMnimator 9:aeda90624ad0 73 {
reARMnimator 9:aeda90624ad0 74 DS28EC20::Scratchpad scratchpad;
reARMnimator 9:aeda90624ad0 75
reARMnimator 9:aeda90624ad0 76 DS28EC20::Address offset = inAddress - (inAddress & ~(DS28EC20::pageSizeBytes - 1));
reARMnimator 9:aeda90624ad0 77 DS28EC20::Address targetAddress = inAddress - offset;
reARMnimator 9:aeda90624ad0 78
reARMnimator 9:aeda90624ad0 79 uint_least8_t *p_Data = scratchpad.data();
reARMnimator 9:aeda90624ad0 80 p_Data += offset;
reARMnimator 9:aeda90624ad0 81
reARMnimator 9:aeda90624ad0 82 MaximInterface::error_code error;
reARMnimator 9:aeda90624ad0 83 size_t readLen = (dataLen + offset);
reARMnimator 9:aeda90624ad0 84
reARMnimator 9:aeda90624ad0 85 /* ... Align length to page boundary */
reARMnimator 9:aeda90624ad0 86 readLen += readLen + (DS28EC20::pageSizeBytes - 1u);
reARMnimator 9:aeda90624ad0 87 readLen &= ~(DS28EC20::pageSizeBytes - 1u);
reARMnimator 9:aeda90624ad0 88
reARMnimator 9:aeda90624ad0 89 for (size_t writeLen = 0u; writeLen < readLen; writeLen += DS28EC20::pageSizeBytes) {
reARMnimator 9:aeda90624ad0 90 if (offset && dataLen){
reARMnimator 9:aeda90624ad0 91 error = device.readMemoryExt(targetAddress, scratchpad.data(), DS28EC20::pageSizeBytes);
reARMnimator 9:aeda90624ad0 92 }
reARMnimator 9:aeda90624ad0 93
reARMnimator 9:aeda90624ad0 94 if (error) {
reARMnimator 9:aeda90624ad0 95 return error;
reARMnimator 9:aeda90624ad0 96 }
reARMnimator 9:aeda90624ad0 97
reARMnimator 9:aeda90624ad0 98 if (dataLen) {
reARMnimator 9:aeda90624ad0 99 if (dataLen >= DS28EC20::pageSizeBytes) {
reARMnimator 9:aeda90624ad0 100 (void)memcpy(p_Data, dataIn, DS28EC20::pageSizeBytes);
reARMnimator 9:aeda90624ad0 101 dataIn += DS28EC20::pageSizeBytes;
reARMnimator 9:aeda90624ad0 102 dataLen -= DS28EC20::pageSizeBytes;
reARMnimator 9:aeda90624ad0 103 }
reARMnimator 9:aeda90624ad0 104 else {
reARMnimator 9:aeda90624ad0 105 (void)memcpy(p_Data, dataIn, dataLen);
reARMnimator 9:aeda90624ad0 106 dataLen = 0;
reARMnimator 9:aeda90624ad0 107 }
reARMnimator 9:aeda90624ad0 108 p_Data = scratchpad.data();
reARMnimator 9:aeda90624ad0 109 }
reARMnimator 9:aeda90624ad0 110
reARMnimator 9:aeda90624ad0 111 error = writeMemory(device, targetAddress, scratchpad);
reARMnimator 9:aeda90624ad0 112 targetAddress += DS28EC20::pageSizeBytes;
reARMnimator 9:aeda90624ad0 113
reARMnimator 9:aeda90624ad0 114 if (error) {
reARMnimator 9:aeda90624ad0 115 return error;
reARMnimator 9:aeda90624ad0 116 }
reARMnimator 9:aeda90624ad0 117
reARMnimator 9:aeda90624ad0 118 offset = 0;
reARMnimator 9:aeda90624ad0 119 }
reARMnimator 9:aeda90624ad0 120
reARMnimator 9:aeda90624ad0 121 return error;
reARMnimator 9:aeda90624ad0 122 }
reARMnimator 9:aeda90624ad0 123
reARMnimator 9:aeda90624ad0 124
reARMnimator 9:aeda90624ad0 125 /* TODO: Test readMemory */
reARMnimator 9:aeda90624ad0 126 error_code DS28EC20::readMemory(Address beginAddress, uint_least8_t * data,
reARMnimator 9:aeda90624ad0 127 size_t dataLen) const {
reARMnimator 9:aeda90624ad0 128 error_code owmResult = selectRom(*master);
reARMnimator 9:aeda90624ad0 129 if (owmResult) {
reARMnimator 9:aeda90624ad0 130 return owmResult;
reARMnimator 9:aeda90624ad0 131 }
reARMnimator 9:aeda90624ad0 132 const uint_least8_t sendBlock[] = {ReadMemory, static_cast<uint_least8_t>(beginAddress), static_cast<uint_least8_t>(beginAddress >> 8)};
reARMnimator 9:aeda90624ad0 133 owmResult =
reARMnimator 9:aeda90624ad0 134 master->writeBlock(make_span(sendBlock, sizeof(sendBlock) / sizeof(sendBlock[0])));
reARMnimator 9:aeda90624ad0 135 if (owmResult) {
reARMnimator 9:aeda90624ad0 136 return owmResult;
reARMnimator 9:aeda90624ad0 137 }
reARMnimator 9:aeda90624ad0 138 owmResult = master->readBlock(make_span(data, dataLen));
reARMnimator 9:aeda90624ad0 139 return owmResult;
reARMnimator 9:aeda90624ad0 140 }
reARMnimator 9:aeda90624ad0 141
reARMnimator 9:aeda90624ad0 142 #if 0
reARMnimator 9:aeda90624ad0 143 static unsigned short crc16(const unsigned char* pin, int sz, unsigned short crc_in)
reARMnimator 9:aeda90624ad0 144 {
reARMnimator 9:aeda90624ad0 145 unsigned short crc = crc_in;
reARMnimator 9:aeda90624ad0 146 unsigned short tmp, in;
reARMnimator 9:aeda90624ad0 147 int i, index, bit;
reARMnimator 9:aeda90624ad0 148 for (index = 0, bit = 0, i = 0; i < 8 * sz; i++) {
reARMnimator 9:aeda90624ad0 149 in = pin[index];
reARMnimator 9:aeda90624ad0 150 in >>= (bit);
reARMnimator 9:aeda90624ad0 151 tmp = (crc & 0x8000);
reARMnimator 9:aeda90624ad0 152 tmp >>= 15;
reARMnimator 9:aeda90624ad0 153 in ^= tmp;
reARMnimator 9:aeda90624ad0 154 in &= 1;
reARMnimator 9:aeda90624ad0 155 bit++;
reARMnimator 9:aeda90624ad0 156 if (bit >= 8) {
reARMnimator 9:aeda90624ad0 157 bit = 0;
reARMnimator 9:aeda90624ad0 158 index++;
reARMnimator 9:aeda90624ad0 159 }
reARMnimator 9:aeda90624ad0 160
reARMnimator 9:aeda90624ad0 161 crc <<= 1;
reARMnimator 9:aeda90624ad0 162 tmp = crc;
reARMnimator 9:aeda90624ad0 163 tmp &= 0x8004;
reARMnimator 9:aeda90624ad0 164 if (in) {
reARMnimator 9:aeda90624ad0 165 tmp ^= 0x8004;
reARMnimator 9:aeda90624ad0 166 tmp &= 0x8004;
reARMnimator 9:aeda90624ad0 167 }
reARMnimator 9:aeda90624ad0 168 crc &= (~0x8004);
reARMnimator 9:aeda90624ad0 169 crc |= tmp;
reARMnimator 9:aeda90624ad0 170 if (in)
reARMnimator 9:aeda90624ad0 171 crc |= 1;
reARMnimator 9:aeda90624ad0 172 else
reARMnimator 9:aeda90624ad0 173 crc &= (~1);
reARMnimator 9:aeda90624ad0 174 }
reARMnimator 9:aeda90624ad0 175
reARMnimator 9:aeda90624ad0 176 tmp = (crc & 1);
reARMnimator 9:aeda90624ad0 177 for (i = 0; i < 15; i++) {
reARMnimator 9:aeda90624ad0 178 tmp <<= 1;
reARMnimator 9:aeda90624ad0 179 crc >>= 1;
reARMnimator 9:aeda90624ad0 180 tmp |= (crc & 1);
reARMnimator 9:aeda90624ad0 181 }
reARMnimator 9:aeda90624ad0 182 return ~tmp;
reARMnimator 9:aeda90624ad0 183 }
reARMnimator 9:aeda90624ad0 184
reARMnimator 9:aeda90624ad0 185 # define CRC16(...)\
reARMnimator 9:aeda90624ad0 186 crc16(__VA_ARGS__)
reARMnimator 9:aeda90624ad0 187 #else
reARMnimator 9:aeda90624ad0 188 # define CRC16(data, len, ...)\
reARMnimator 9:aeda90624ad0 189 calculateCrc16(make_span(data, len), __VA_ARGS__)
reARMnimator 9:aeda90624ad0 190 #endif
reARMnimator 9:aeda90624ad0 191
reARMnimator 9:aeda90624ad0 192 #define PAGE_SIZE_BYTES 32
reARMnimator 9:aeda90624ad0 193 #define CRC_LEN_BYTES 2
reARMnimator 9:aeda90624ad0 194
reARMnimator 9:aeda90624ad0 195
reARMnimator 9:aeda90624ad0 196 static error_code processCrc16(OneWireMaster *master, uint_least16_t & crcLocal)
reARMnimator 9:aeda90624ad0 197 {
reARMnimator 9:aeda90624ad0 198 /* ... Read CRC */
reARMnimator 9:aeda90624ad0 199 uint_least8_t crcRemote[CRC_LEN_BYTES];
reARMnimator 9:aeda90624ad0 200 error_code owmResult = master->readBlock(make_span(&crcRemote[0], sizeof(crcRemote) / sizeof(crcRemote[0])));
reARMnimator 9:aeda90624ad0 201
reARMnimator 9:aeda90624ad0 202 if (owmResult) {
reARMnimator 9:aeda90624ad0 203 return owmResult;
reARMnimator 9:aeda90624ad0 204 }
reARMnimator 9:aeda90624ad0 205
reARMnimator 9:aeda90624ad0 206 crcLocal = ~crcLocal;
reARMnimator 9:aeda90624ad0 207 crcLocal ^= crcRemote[0] | (static_cast<uint_least16_t>(crcRemote[1]) << 8);
reARMnimator 9:aeda90624ad0 208
reARMnimator 9:aeda90624ad0 209 if (crcLocal) {
reARMnimator 9:aeda90624ad0 210 owmResult = make_error_code(DS28EC20::CrcError);
reARMnimator 9:aeda90624ad0 211 return owmResult;
reARMnimator 9:aeda90624ad0 212 }
reARMnimator 9:aeda90624ad0 213
reARMnimator 9:aeda90624ad0 214 crcLocal = 0;
reARMnimator 9:aeda90624ad0 215
reARMnimator 9:aeda90624ad0 216 return owmResult;
reARMnimator 9:aeda90624ad0 217 }
reARMnimator 9:aeda90624ad0 218
reARMnimator 9:aeda90624ad0 219
reARMnimator 9:aeda90624ad0 220 error_code DS28EC20::readMemoryExt(Address beginAddress, uint_least8_t * data,
reARMnimator 9:aeda90624ad0 221 size_t dataLen) const
reARMnimator 9:aeda90624ad0 222 {
reARMnimator 9:aeda90624ad0 223 error_code owmResult = selectRom(*master);
reARMnimator 9:aeda90624ad0 224 if (owmResult) {
reARMnimator 9:aeda90624ad0 225 return owmResult;
reARMnimator 9:aeda90624ad0 226 }
reARMnimator 9:aeda90624ad0 227
reARMnimator 9:aeda90624ad0 228 uint_least8_t addressMsb = static_cast<uint_least8_t>(beginAddress >> 8);
reARMnimator 9:aeda90624ad0 229 uint_least8_t addressLsb = static_cast<uint_least8_t>(beginAddress >> 0);
reARMnimator 9:aeda90624ad0 230
reARMnimator 9:aeda90624ad0 231 uint_least8_t offset = addressLsb & ~(PAGE_SIZE_BYTES - 1);
reARMnimator 9:aeda90624ad0 232 offset = addressLsb - offset;
reARMnimator 9:aeda90624ad0 233
reARMnimator 9:aeda90624ad0 234 const uint_least8_t sendBlock[] = { ReadMemoryExt, static_cast<uint_least8_t>(addressLsb - offset), addressMsb };
reARMnimator 9:aeda90624ad0 235 owmResult = master->writeBlock(make_span(sendBlock, sizeof(sendBlock) / sizeof(sendBlock[0])));
reARMnimator 9:aeda90624ad0 236
reARMnimator 9:aeda90624ad0 237 if (owmResult) {
reARMnimator 9:aeda90624ad0 238 return owmResult;
reARMnimator 9:aeda90624ad0 239 }
reARMnimator 9:aeda90624ad0 240
reARMnimator 9:aeda90624ad0 241 uint_least16_t crcLocal = 0;
reARMnimator 9:aeda90624ad0 242
reARMnimator 9:aeda90624ad0 243 /* ... Calculate CRC of control fields */
reARMnimator 9:aeda90624ad0 244 crcLocal = CRC16(&sendBlock[0], sizeof(sendBlock) / sizeof(sendBlock[0]), crcLocal);
reARMnimator 9:aeda90624ad0 245
reARMnimator 9:aeda90624ad0 246 uint_least8_t byte = 0;
reARMnimator 9:aeda90624ad0 247 /* ... Calculate CRC of head bytes */
reARMnimator 9:aeda90624ad0 248 {
reARMnimator 9:aeda90624ad0 249 uint32_t n = offset;
reARMnimator 9:aeda90624ad0 250 while (n--) {
reARMnimator 9:aeda90624ad0 251 owmResult = master->readByte(byte);
reARMnimator 9:aeda90624ad0 252 crcLocal = CRC16(&byte, sizeof(byte), crcLocal);
reARMnimator 9:aeda90624ad0 253 }
reARMnimator 9:aeda90624ad0 254 }
reARMnimator 9:aeda90624ad0 255
reARMnimator 9:aeda90624ad0 256 /* ... Read data blocks */
reARMnimator 9:aeda90624ad0 257 const size_t blockCnt = dataLen / PAGE_SIZE_BYTES;
reARMnimator 9:aeda90624ad0 258 size_t blockLen = PAGE_SIZE_BYTES - offset;
reARMnimator 9:aeda90624ad0 259 for (size_t block = 0; block < blockCnt; ++block)
reARMnimator 9:aeda90624ad0 260 {
reARMnimator 9:aeda90624ad0 261 /* ... Read data */
reARMnimator 9:aeda90624ad0 262 owmResult = master->readBlock(make_span(data, blockLen));
reARMnimator 9:aeda90624ad0 263
reARMnimator 9:aeda90624ad0 264 if (owmResult) {
reARMnimator 9:aeda90624ad0 265 return owmResult;
reARMnimator 9:aeda90624ad0 266 }
reARMnimator 9:aeda90624ad0 267
reARMnimator 9:aeda90624ad0 268 /* ... Calculate CRC of data */
reARMnimator 9:aeda90624ad0 269 crcLocal = CRC16(data, blockLen, crcLocal);
reARMnimator 9:aeda90624ad0 270 data += blockLen;
reARMnimator 9:aeda90624ad0 271
reARMnimator 9:aeda90624ad0 272 /* ... Read CRC */
reARMnimator 9:aeda90624ad0 273 owmResult = processCrc16(master, crcLocal);
reARMnimator 9:aeda90624ad0 274
reARMnimator 9:aeda90624ad0 275 if (owmResult) {
reARMnimator 9:aeda90624ad0 276 return owmResult;
reARMnimator 9:aeda90624ad0 277 }
reARMnimator 9:aeda90624ad0 278
reARMnimator 9:aeda90624ad0 279 blockLen = PAGE_SIZE_BYTES;
reARMnimator 9:aeda90624ad0 280 }
reARMnimator 9:aeda90624ad0 281
reARMnimator 9:aeda90624ad0 282
reARMnimator 9:aeda90624ad0 283 /* ... Read data reminder */
reARMnimator 9:aeda90624ad0 284 size_t dataBlockLen = 0;
reARMnimator 9:aeda90624ad0 285 size_t remLen = 0;
reARMnimator 9:aeda90624ad0 286 if (PAGE_SIZE_BYTES > blockLen)
reARMnimator 9:aeda90624ad0 287 {
reARMnimator 9:aeda90624ad0 288
reARMnimator 9:aeda90624ad0 289 /* ... Total amount of user data is less than one block */
reARMnimator 9:aeda90624ad0 290 if (PAGE_SIZE_BYTES > (offset + dataLen)) {
reARMnimator 9:aeda90624ad0 291 /* ... Total length does not cross block boundary.
reARMnimator 9:aeda90624ad0 292 * Read till the end of block. */
reARMnimator 9:aeda90624ad0 293 dataBlockLen = dataLen;
reARMnimator 9:aeda90624ad0 294 remLen = blockLen - dataBlockLen;
reARMnimator 9:aeda90624ad0 295
reARMnimator 9:aeda90624ad0 296 }
reARMnimator 9:aeda90624ad0 297 else {
reARMnimator 9:aeda90624ad0 298 /* ... Total length is longer than one block.
reARMnimator 9:aeda90624ad0 299 * Read till the end of block and then the rest. */
reARMnimator 9:aeda90624ad0 300 dataBlockLen = blockLen;
reARMnimator 9:aeda90624ad0 301
reARMnimator 9:aeda90624ad0 302 /* ... Read data */
reARMnimator 9:aeda90624ad0 303 owmResult = master->readBlock(make_span(data, dataBlockLen));
reARMnimator 9:aeda90624ad0 304
reARMnimator 9:aeda90624ad0 305 if (owmResult) {
reARMnimator 9:aeda90624ad0 306 return owmResult;
reARMnimator 9:aeda90624ad0 307 }
reARMnimator 9:aeda90624ad0 308
reARMnimator 9:aeda90624ad0 309 /* ... Calculate CRC of data */
reARMnimator 9:aeda90624ad0 310 crcLocal = CRC16(data, dataBlockLen, crcLocal);
reARMnimator 9:aeda90624ad0 311 data += dataBlockLen;
reARMnimator 9:aeda90624ad0 312
reARMnimator 9:aeda90624ad0 313 /* ... Read CRC */
reARMnimator 9:aeda90624ad0 314 owmResult = processCrc16(master, crcLocal);
reARMnimator 9:aeda90624ad0 315
reARMnimator 9:aeda90624ad0 316 if (owmResult) {
reARMnimator 9:aeda90624ad0 317 return owmResult;
reARMnimator 9:aeda90624ad0 318 }
reARMnimator 9:aeda90624ad0 319
reARMnimator 9:aeda90624ad0 320 dataBlockLen = dataLen - dataBlockLen;
reARMnimator 9:aeda90624ad0 321 remLen = PAGE_SIZE_BYTES - dataBlockLen;
reARMnimator 9:aeda90624ad0 322 }
reARMnimator 9:aeda90624ad0 323
reARMnimator 9:aeda90624ad0 324 }
reARMnimator 9:aeda90624ad0 325 else
reARMnimator 9:aeda90624ad0 326 {
reARMnimator 9:aeda90624ad0 327 /* ... Total amount of data is more than one block */
reARMnimator 9:aeda90624ad0 328 dataBlockLen = dataLen % PAGE_SIZE_BYTES;
reARMnimator 9:aeda90624ad0 329 remLen = PAGE_SIZE_BYTES - dataBlockLen;
reARMnimator 9:aeda90624ad0 330 }
reARMnimator 9:aeda90624ad0 331
reARMnimator 9:aeda90624ad0 332 /* ... Read data */
reARMnimator 9:aeda90624ad0 333 owmResult = master->readBlock(make_span(data, dataBlockLen));
reARMnimator 9:aeda90624ad0 334
reARMnimator 9:aeda90624ad0 335 if (owmResult) {
reARMnimator 9:aeda90624ad0 336 return owmResult;
reARMnimator 9:aeda90624ad0 337 }
reARMnimator 9:aeda90624ad0 338
reARMnimator 9:aeda90624ad0 339 /* ... Calculate CRC of data */
reARMnimator 9:aeda90624ad0 340 crcLocal = CRC16(data, dataBlockLen, crcLocal);
reARMnimator 9:aeda90624ad0 341 data += dataBlockLen;
reARMnimator 9:aeda90624ad0 342
reARMnimator 9:aeda90624ad0 343 /* ... Read tail */
reARMnimator 9:aeda90624ad0 344 while (remLen--) {
reARMnimator 9:aeda90624ad0 345 owmResult = master->readByte(byte);
reARMnimator 9:aeda90624ad0 346 crcLocal = CRC16(&byte, sizeof(byte), crcLocal);
reARMnimator 9:aeda90624ad0 347
reARMnimator 9:aeda90624ad0 348 if (owmResult) {
reARMnimator 9:aeda90624ad0 349 return owmResult;
reARMnimator 9:aeda90624ad0 350 }
reARMnimator 9:aeda90624ad0 351 }
reARMnimator 9:aeda90624ad0 352
reARMnimator 9:aeda90624ad0 353 /* ... Read CRC */
reARMnimator 9:aeda90624ad0 354 owmResult = processCrc16(master, crcLocal);
reARMnimator 9:aeda90624ad0 355
reARMnimator 9:aeda90624ad0 356 if (owmResult) {
reARMnimator 9:aeda90624ad0 357 return owmResult;
reARMnimator 9:aeda90624ad0 358 }
reARMnimator 9:aeda90624ad0 359
reARMnimator 9:aeda90624ad0 360 return owmResult;
reARMnimator 9:aeda90624ad0 361 }
reARMnimator 9:aeda90624ad0 362
reARMnimator 9:aeda90624ad0 363
reARMnimator 9:aeda90624ad0 364 error_code DS28EC20::writeScratchpad(Address targetAddress,
reARMnimator 9:aeda90624ad0 365 const Scratchpad & data) {
reARMnimator 9:aeda90624ad0 366 error_code owmResult = selectRom(*master);
reARMnimator 9:aeda90624ad0 367 if (owmResult) {
reARMnimator 9:aeda90624ad0 368 return owmResult;
reARMnimator 9:aeda90624ad0 369 }
reARMnimator 9:aeda90624ad0 370
reARMnimator 9:aeda90624ad0 371 uint_least8_t addressMsb = static_cast<uint_least8_t>(targetAddress >> 8);
reARMnimator 9:aeda90624ad0 372 uint_least8_t addressLsb = static_cast<uint_least8_t>(targetAddress >> 0);
reARMnimator 9:aeda90624ad0 373 addressLsb &= ~(pageSizeBytes - 1);
reARMnimator 9:aeda90624ad0 374
reARMnimator 9:aeda90624ad0 375 array<uint_least8_t, 3 + Scratchpad::csize> block;
reARMnimator 9:aeda90624ad0 376 block[0] = WriteScratchpad;
reARMnimator 9:aeda90624ad0 377 block[1] = addressLsb;
reARMnimator 9:aeda90624ad0 378 block[2] = addressMsb;
reARMnimator 9:aeda90624ad0 379
reARMnimator 9:aeda90624ad0 380 std::copy(data.begin(), data.end(), block.begin() + 3);
reARMnimator 9:aeda90624ad0 381 owmResult = master->writeBlock(make_span(block.data(), block.size()));
reARMnimator 9:aeda90624ad0 382 if (owmResult) {
reARMnimator 9:aeda90624ad0 383 return owmResult;
reARMnimator 9:aeda90624ad0 384 }
reARMnimator 9:aeda90624ad0 385 const uint_fast16_t calculatedCrc = calculateCrc16(make_span(block.data(), block.size())) ^ 0xFFFFU;
reARMnimator 9:aeda90624ad0 386 owmResult = master->readBlock(make_span(block.data(), 2));
reARMnimator 9:aeda90624ad0 387 if (owmResult) {
reARMnimator 9:aeda90624ad0 388 return owmResult;
reARMnimator 9:aeda90624ad0 389 }
reARMnimator 9:aeda90624ad0 390 if (calculatedCrc !=
reARMnimator 9:aeda90624ad0 391 ((static_cast<uint_fast16_t>(block[1]) << 8) | block[0])) {
reARMnimator 9:aeda90624ad0 392 owmResult = make_error_code(CrcError);
reARMnimator 9:aeda90624ad0 393 }
reARMnimator 9:aeda90624ad0 394 return owmResult;
reARMnimator 9:aeda90624ad0 395 }
reARMnimator 9:aeda90624ad0 396
reARMnimator 9:aeda90624ad0 397 error_code DS28EC20::readScratchpad(Scratchpad & data, uint_least8_t & esByte) {
reARMnimator 9:aeda90624ad0 398 typedef array<uint_least8_t, 6 + Scratchpad::csize> Block;
reARMnimator 9:aeda90624ad0 399
reARMnimator 9:aeda90624ad0 400 error_code owmResult = selectRom(*master);
reARMnimator 9:aeda90624ad0 401 if (owmResult) {
reARMnimator 9:aeda90624ad0 402 return owmResult;
reARMnimator 9:aeda90624ad0 403 }
reARMnimator 9:aeda90624ad0 404 Block block; block[0] = ReadScratchpad;
reARMnimator 9:aeda90624ad0 405 owmResult = master->writeByte(block.front());
reARMnimator 9:aeda90624ad0 406 if (owmResult) {
reARMnimator 9:aeda90624ad0 407 return owmResult;
reARMnimator 9:aeda90624ad0 408 }
reARMnimator 9:aeda90624ad0 409 owmResult = master->readBlock(make_span(block.data() + 1, block.size() - 1));
reARMnimator 9:aeda90624ad0 410 if (owmResult) {
reARMnimator 9:aeda90624ad0 411 return owmResult;
reARMnimator 9:aeda90624ad0 412 }
reARMnimator 9:aeda90624ad0 413 Block::const_iterator blockIt = block.end();
reARMnimator 9:aeda90624ad0 414 uint_fast16_t receivedCrc = static_cast<uint_fast16_t>(*(--blockIt)) << 8;
reARMnimator 9:aeda90624ad0 415 receivedCrc |= *(--blockIt);
reARMnimator 9:aeda90624ad0 416 const uint_fast16_t expectedCrc = calculateCrc16(make_span(block.data(), block.size() - 2)) ^ 0xFFFFU;
reARMnimator 9:aeda90624ad0 417 if (expectedCrc == receivedCrc) {
reARMnimator 9:aeda90624ad0 418 Block::const_iterator blockItEnd = blockIt;
reARMnimator 9:aeda90624ad0 419 blockIt -= data.size();
reARMnimator 9:aeda90624ad0 420 std::copy(blockIt, blockItEnd, data.begin());
reARMnimator 9:aeda90624ad0 421 esByte = *(--blockIt);
reARMnimator 9:aeda90624ad0 422 } else {
reARMnimator 9:aeda90624ad0 423 owmResult = make_error_code(CrcError);
reARMnimator 9:aeda90624ad0 424 }
reARMnimator 9:aeda90624ad0 425 return owmResult;
reARMnimator 9:aeda90624ad0 426 }
reARMnimator 9:aeda90624ad0 427
reARMnimator 9:aeda90624ad0 428 /* TODO: Test copyScratchpad */
reARMnimator 9:aeda90624ad0 429 error_code DS28EC20::copyScratchpad(Address targetAddress, uint_least8_t esByte) {
reARMnimator 9:aeda90624ad0 430 error_code owmResult = selectRom(*master);
reARMnimator 9:aeda90624ad0 431 if (owmResult) {
reARMnimator 9:aeda90624ad0 432 return owmResult;
reARMnimator 9:aeda90624ad0 433 }
reARMnimator 9:aeda90624ad0 434
reARMnimator 9:aeda90624ad0 435 uint_least8_t addressMsb = static_cast<uint_least8_t>(targetAddress >> 8);
reARMnimator 9:aeda90624ad0 436 uint_least8_t addressLsb = static_cast<uint_least8_t>(targetAddress >> 0);
reARMnimator 9:aeda90624ad0 437 addressLsb &= ~(pageSizeBytes - 1);
reARMnimator 9:aeda90624ad0 438
reARMnimator 9:aeda90624ad0 439 uint_least8_t block[] = {CopyScratchpad, addressLsb, addressMsb};
reARMnimator 9:aeda90624ad0 440
reARMnimator 9:aeda90624ad0 441 owmResult = master->writeBlock(make_span(block, sizeof(block) / sizeof(block[0])));
reARMnimator 9:aeda90624ad0 442 if (owmResult) {
reARMnimator 9:aeda90624ad0 443 return owmResult;
reARMnimator 9:aeda90624ad0 444 }
reARMnimator 9:aeda90624ad0 445 owmResult = master->writeByteSetLevel(esByte, OneWireMaster::StrongLevel);
reARMnimator 9:aeda90624ad0 446 if (owmResult) {
reARMnimator 9:aeda90624ad0 447 return owmResult;
reARMnimator 9:aeda90624ad0 448 }
reARMnimator 9:aeda90624ad0 449 (*sleep)(10);
reARMnimator 9:aeda90624ad0 450 owmResult = master->setLevel(OneWireMaster::NormalLevel);
reARMnimator 9:aeda90624ad0 451 if (owmResult) {
reARMnimator 9:aeda90624ad0 452 return owmResult;
reARMnimator 9:aeda90624ad0 453 }
reARMnimator 9:aeda90624ad0 454 owmResult = master->readByte(block[0]);
reARMnimator 9:aeda90624ad0 455 if (owmResult) {
reARMnimator 9:aeda90624ad0 456 return owmResult;
reARMnimator 9:aeda90624ad0 457 }
reARMnimator 9:aeda90624ad0 458 if (block[0] != 0xAA) {
reARMnimator 9:aeda90624ad0 459 owmResult = make_error_code(OperationFailure);
reARMnimator 9:aeda90624ad0 460 }
reARMnimator 9:aeda90624ad0 461 return owmResult;
reARMnimator 9:aeda90624ad0 462 }
reARMnimator 9:aeda90624ad0 463
reARMnimator 9:aeda90624ad0 464 const error_category & DS28EC20::errorCategory() {
reARMnimator 9:aeda90624ad0 465 static class : public error_category {
reARMnimator 9:aeda90624ad0 466 public:
reARMnimator 9:aeda90624ad0 467 virtual const char * name() const { return "DS28EC20"; }
reARMnimator 9:aeda90624ad0 468
reARMnimator 9:aeda90624ad0 469 virtual std::string message(int condition) const {
reARMnimator 9:aeda90624ad0 470 switch (condition) {
reARMnimator 9:aeda90624ad0 471 case CrcError:
reARMnimator 9:aeda90624ad0 472 return "CRC Error";
reARMnimator 9:aeda90624ad0 473
reARMnimator 9:aeda90624ad0 474 case OperationFailure:
reARMnimator 9:aeda90624ad0 475 return "Operation Failure";
reARMnimator 9:aeda90624ad0 476
reARMnimator 9:aeda90624ad0 477 default:
reARMnimator 9:aeda90624ad0 478 return defaultErrorMessage(condition);
reARMnimator 9:aeda90624ad0 479 }
reARMnimator 9:aeda90624ad0 480 }
reARMnimator 9:aeda90624ad0 481 } instance;
reARMnimator 9:aeda90624ad0 482 return instance;
reARMnimator 9:aeda90624ad0 483 }
reARMnimator 9:aeda90624ad0 484
reARMnimator 9:aeda90624ad0 485 } // namespace MaximInterface