Extended MaximInterface

Dependents:   mbed_DS28EC20_GPIO

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

Who changed what in which revision?

UserRevisionLine numberNew contents of line
IanBenzMaxim 6:a8c83a2e6fa4 1 /*******************************************************************************
IanBenzMaxim 6:a8c83a2e6fa4 2 * Copyright (C) 2018 Maxim Integrated Products, Inc., All Rights Reserved.
IanBenzMaxim 6:a8c83a2e6fa4 3 *
IanBenzMaxim 6:a8c83a2e6fa4 4 * Permission is hereby granted, free of charge, to any person obtaining a
IanBenzMaxim 6:a8c83a2e6fa4 5 * copy of this software and associated documentation files (the "Software"),
IanBenzMaxim 6:a8c83a2e6fa4 6 * to deal in the Software without restriction, including without limitation
IanBenzMaxim 6:a8c83a2e6fa4 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
IanBenzMaxim 6:a8c83a2e6fa4 8 * and/or sell copies of the Software, and to permit persons to whom the
IanBenzMaxim 6:a8c83a2e6fa4 9 * Software is furnished to do so, subject to the following conditions:
IanBenzMaxim 6:a8c83a2e6fa4 10 *
IanBenzMaxim 6:a8c83a2e6fa4 11 * The above copyright notice and this permission notice shall be included
IanBenzMaxim 6:a8c83a2e6fa4 12 * in all copies or substantial portions of the Software.
IanBenzMaxim 6:a8c83a2e6fa4 13 *
IanBenzMaxim 6:a8c83a2e6fa4 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
IanBenzMaxim 6:a8c83a2e6fa4 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
IanBenzMaxim 6:a8c83a2e6fa4 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IanBenzMaxim 6:a8c83a2e6fa4 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
IanBenzMaxim 6:a8c83a2e6fa4 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
IanBenzMaxim 6:a8c83a2e6fa4 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
IanBenzMaxim 6:a8c83a2e6fa4 20 * OTHER DEALINGS IN THE SOFTWARE.
IanBenzMaxim 6:a8c83a2e6fa4 21 *
IanBenzMaxim 6:a8c83a2e6fa4 22 * Except as contained in this notice, the name of Maxim Integrated
IanBenzMaxim 6:a8c83a2e6fa4 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
IanBenzMaxim 6:a8c83a2e6fa4 24 * Products, Inc. Branding Policy.
IanBenzMaxim 6:a8c83a2e6fa4 25 *
IanBenzMaxim 6:a8c83a2e6fa4 26 * The mere transfer of this software does not imply any licenses
IanBenzMaxim 6:a8c83a2e6fa4 27 * of trade secrets, proprietary technology, copyrights, patents,
IanBenzMaxim 6:a8c83a2e6fa4 28 * trademarks, maskwork rights, or any other form of intellectual
IanBenzMaxim 6:a8c83a2e6fa4 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
IanBenzMaxim 6:a8c83a2e6fa4 30 * ownership rights.
IanBenzMaxim 6:a8c83a2e6fa4 31 *******************************************************************************/
IanBenzMaxim 6:a8c83a2e6fa4 32
IanBenzMaxim 6:a8c83a2e6fa4 33 #include <MaximInterface/Utilities/crc.hpp>
IanBenzMaxim 6:a8c83a2e6fa4 34 #include <MaximInterface/Utilities/Error.hpp>
IanBenzMaxim 6:a8c83a2e6fa4 35 #include "I2CMaster.hpp"
IanBenzMaxim 6:a8c83a2e6fa4 36 #include "OneWireMaster.hpp"
IanBenzMaxim 6:a8c83a2e6fa4 37 #include "Sleep.hpp"
IanBenzMaxim 6:a8c83a2e6fa4 38 #include "RunCommand.hpp"
IanBenzMaxim 6:a8c83a2e6fa4 39
IanBenzMaxim 6:a8c83a2e6fa4 40 namespace MaximInterface {
IanBenzMaxim 6:a8c83a2e6fa4 41
IanBenzMaxim 6:a8c83a2e6fa4 42 const error_category & RunCommandWithOneWireMaster::errorCategory() {
IanBenzMaxim 6:a8c83a2e6fa4 43 static class : public error_category {
IanBenzMaxim 6:a8c83a2e6fa4 44 public:
IanBenzMaxim 6:a8c83a2e6fa4 45 virtual const char * name() const { return "RunCommandWithOneWireMaster"; }
IanBenzMaxim 6:a8c83a2e6fa4 46
IanBenzMaxim 6:a8c83a2e6fa4 47 virtual std::string message(int condition) const {
IanBenzMaxim 6:a8c83a2e6fa4 48 switch (condition) {
IanBenzMaxim 6:a8c83a2e6fa4 49 case CrcError:
IanBenzMaxim 6:a8c83a2e6fa4 50 return "CRC Error";
IanBenzMaxim 6:a8c83a2e6fa4 51
IanBenzMaxim 6:a8c83a2e6fa4 52 case InvalidResponseError:
IanBenzMaxim 6:a8c83a2e6fa4 53 return "Invalid Response Error";
IanBenzMaxim 6:a8c83a2e6fa4 54 }
IanBenzMaxim 6:a8c83a2e6fa4 55 return defaultErrorMessage(condition);
IanBenzMaxim 6:a8c83a2e6fa4 56 }
IanBenzMaxim 6:a8c83a2e6fa4 57 } instance;
IanBenzMaxim 6:a8c83a2e6fa4 58 return instance;
IanBenzMaxim 6:a8c83a2e6fa4 59 }
IanBenzMaxim 6:a8c83a2e6fa4 60
IanBenzMaxim 6:a8c83a2e6fa4 61 error_code RunCommandWithOneWireMaster::
IanBenzMaxim 6:a8c83a2e6fa4 62 operator()(span<const uint_least8_t> command, int delayTime,
IanBenzMaxim 6:a8c83a2e6fa4 63 span<uint_least8_t> & response) const {
IanBenzMaxim 6:a8c83a2e6fa4 64 // Write command.
IanBenzMaxim 6:a8c83a2e6fa4 65 error_code result = selectRom(*master);
IanBenzMaxim 6:a8c83a2e6fa4 66 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 67 return result;
IanBenzMaxim 6:a8c83a2e6fa4 68 }
IanBenzMaxim 6:a8c83a2e6fa4 69 uint_least8_t xpcBuffer[2] = {0x66,
IanBenzMaxim 6:a8c83a2e6fa4 70 static_cast<uint_least8_t>(command.size())};
IanBenzMaxim 6:a8c83a2e6fa4 71 result = master->writeBlock(xpcBuffer);
IanBenzMaxim 6:a8c83a2e6fa4 72 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 73 return result;
IanBenzMaxim 6:a8c83a2e6fa4 74 }
IanBenzMaxim 6:a8c83a2e6fa4 75 result = master->writeBlock(command);
IanBenzMaxim 6:a8c83a2e6fa4 76 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 77 return result;
IanBenzMaxim 6:a8c83a2e6fa4 78 }
IanBenzMaxim 6:a8c83a2e6fa4 79 uint_fast16_t expectedCrc =
IanBenzMaxim 6:a8c83a2e6fa4 80 calculateCrc16(command, calculateCrc16(xpcBuffer)) ^ 0xFFFFU;
IanBenzMaxim 6:a8c83a2e6fa4 81 result = master->readBlock(xpcBuffer);
IanBenzMaxim 6:a8c83a2e6fa4 82 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 83 return result;
IanBenzMaxim 6:a8c83a2e6fa4 84 }
IanBenzMaxim 6:a8c83a2e6fa4 85 if (expectedCrc !=
IanBenzMaxim 6:a8c83a2e6fa4 86 ((static_cast<uint_fast16_t>(xpcBuffer[1]) << 8) | xpcBuffer[0])) {
IanBenzMaxim 6:a8c83a2e6fa4 87 return make_error_code(CrcError);
IanBenzMaxim 6:a8c83a2e6fa4 88 }
IanBenzMaxim 6:a8c83a2e6fa4 89 result = master->writeBytePower(0xAA);
IanBenzMaxim 6:a8c83a2e6fa4 90 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 91 return result;
IanBenzMaxim 6:a8c83a2e6fa4 92 }
IanBenzMaxim 6:a8c83a2e6fa4 93
IanBenzMaxim 6:a8c83a2e6fa4 94 // Wait for device to process.
IanBenzMaxim 6:a8c83a2e6fa4 95 sleep->invoke(delayTime);
IanBenzMaxim 6:a8c83a2e6fa4 96
IanBenzMaxim 6:a8c83a2e6fa4 97 // Read response.
IanBenzMaxim 6:a8c83a2e6fa4 98 result = master->setLevel(OneWireMaster::NormalLevel);
IanBenzMaxim 6:a8c83a2e6fa4 99 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 100 return result;
IanBenzMaxim 6:a8c83a2e6fa4 101 }
IanBenzMaxim 6:a8c83a2e6fa4 102 result = master->readBlock(xpcBuffer);
IanBenzMaxim 6:a8c83a2e6fa4 103 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 104 return result;
IanBenzMaxim 6:a8c83a2e6fa4 105 }
IanBenzMaxim 6:a8c83a2e6fa4 106 if (xpcBuffer[1] > response.size()) {
IanBenzMaxim 6:a8c83a2e6fa4 107 return make_error_code(InvalidResponseError);
IanBenzMaxim 6:a8c83a2e6fa4 108 }
IanBenzMaxim 6:a8c83a2e6fa4 109 response = response.first(xpcBuffer[1]);
IanBenzMaxim 6:a8c83a2e6fa4 110 result = master->readBlock(response);
IanBenzMaxim 6:a8c83a2e6fa4 111 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 112 return result;
IanBenzMaxim 6:a8c83a2e6fa4 113 }
IanBenzMaxim 6:a8c83a2e6fa4 114 expectedCrc =
IanBenzMaxim 6:a8c83a2e6fa4 115 calculateCrc16(response, calculateCrc16(make_span(xpcBuffer + 1, 1))) ^
IanBenzMaxim 6:a8c83a2e6fa4 116 0xFFFFU;
IanBenzMaxim 6:a8c83a2e6fa4 117 result = master->readBlock(xpcBuffer);
IanBenzMaxim 6:a8c83a2e6fa4 118 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 119 return result;
IanBenzMaxim 6:a8c83a2e6fa4 120 }
IanBenzMaxim 6:a8c83a2e6fa4 121 if (expectedCrc !=
IanBenzMaxim 6:a8c83a2e6fa4 122 ((static_cast<uint_fast16_t>(xpcBuffer[1]) << 8) | xpcBuffer[0])) {
IanBenzMaxim 6:a8c83a2e6fa4 123 return make_error_code(CrcError);
IanBenzMaxim 6:a8c83a2e6fa4 124 }
IanBenzMaxim 6:a8c83a2e6fa4 125 return result;
IanBenzMaxim 6:a8c83a2e6fa4 126 }
IanBenzMaxim 6:a8c83a2e6fa4 127
IanBenzMaxim 6:a8c83a2e6fa4 128 const error_category & RunCommandWithI2CMaster::errorCategory() {
IanBenzMaxim 6:a8c83a2e6fa4 129 static class : public error_category {
IanBenzMaxim 6:a8c83a2e6fa4 130 public:
IanBenzMaxim 6:a8c83a2e6fa4 131 virtual const char * name() const { return "RunCommandWithI2CMaster"; }
IanBenzMaxim 6:a8c83a2e6fa4 132
IanBenzMaxim 6:a8c83a2e6fa4 133 virtual std::string message(int condition) const {
IanBenzMaxim 6:a8c83a2e6fa4 134 switch (condition) {
IanBenzMaxim 6:a8c83a2e6fa4 135 case InvalidResponseError:
IanBenzMaxim 6:a8c83a2e6fa4 136 return "Invalid Response Error";
IanBenzMaxim 6:a8c83a2e6fa4 137 }
IanBenzMaxim 6:a8c83a2e6fa4 138 return defaultErrorMessage(condition);
IanBenzMaxim 6:a8c83a2e6fa4 139 }
IanBenzMaxim 6:a8c83a2e6fa4 140 } instance;
IanBenzMaxim 6:a8c83a2e6fa4 141 return instance;
IanBenzMaxim 6:a8c83a2e6fa4 142 }
IanBenzMaxim 6:a8c83a2e6fa4 143
IanBenzMaxim 6:a8c83a2e6fa4 144 error_code RunCommandWithI2CMaster::
IanBenzMaxim 6:a8c83a2e6fa4 145 operator()(span<const uint_least8_t> command, int delayTime,
IanBenzMaxim 6:a8c83a2e6fa4 146 span<uint_least8_t> & response) const {
IanBenzMaxim 6:a8c83a2e6fa4 147 // Write command.
IanBenzMaxim 6:a8c83a2e6fa4 148 error_code result = master->start(address_);
IanBenzMaxim 6:a8c83a2e6fa4 149 if (result == make_error_condition(I2CMaster::NackError) && address_ != 0) {
IanBenzMaxim 6:a8c83a2e6fa4 150 result = master->start(0);
IanBenzMaxim 6:a8c83a2e6fa4 151 }
IanBenzMaxim 6:a8c83a2e6fa4 152 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 153 master->stop();
IanBenzMaxim 6:a8c83a2e6fa4 154 return result;
IanBenzMaxim 6:a8c83a2e6fa4 155 }
IanBenzMaxim 6:a8c83a2e6fa4 156 if (!command.empty()) {
IanBenzMaxim 6:a8c83a2e6fa4 157 result = master->writeByte(command[0]);
IanBenzMaxim 6:a8c83a2e6fa4 158 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 159 master->stop();
IanBenzMaxim 6:a8c83a2e6fa4 160 return result;
IanBenzMaxim 6:a8c83a2e6fa4 161 }
IanBenzMaxim 6:a8c83a2e6fa4 162 command = command.subspan(1);
IanBenzMaxim 6:a8c83a2e6fa4 163 if (!command.empty()) {
IanBenzMaxim 6:a8c83a2e6fa4 164 result = master->writeByte(command.size());
IanBenzMaxim 6:a8c83a2e6fa4 165 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 166 master->stop();
IanBenzMaxim 6:a8c83a2e6fa4 167 return result;
IanBenzMaxim 6:a8c83a2e6fa4 168 }
IanBenzMaxim 6:a8c83a2e6fa4 169 result = master->writeBlock(command);
IanBenzMaxim 6:a8c83a2e6fa4 170 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 171 master->stop();
IanBenzMaxim 6:a8c83a2e6fa4 172 return result;
IanBenzMaxim 6:a8c83a2e6fa4 173 }
IanBenzMaxim 6:a8c83a2e6fa4 174 }
IanBenzMaxim 6:a8c83a2e6fa4 175 }
IanBenzMaxim 6:a8c83a2e6fa4 176 result = master->stop();
IanBenzMaxim 6:a8c83a2e6fa4 177 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 178 return result;
IanBenzMaxim 6:a8c83a2e6fa4 179 }
IanBenzMaxim 6:a8c83a2e6fa4 180
IanBenzMaxim 6:a8c83a2e6fa4 181 // Wait for device to process.
IanBenzMaxim 6:a8c83a2e6fa4 182 sleep->invoke(delayTime);
IanBenzMaxim 6:a8c83a2e6fa4 183
IanBenzMaxim 6:a8c83a2e6fa4 184 // Read response.
IanBenzMaxim 6:a8c83a2e6fa4 185 result = master->start(address_ | 1);
IanBenzMaxim 6:a8c83a2e6fa4 186 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 187 master->stop();
IanBenzMaxim 6:a8c83a2e6fa4 188 return result;
IanBenzMaxim 6:a8c83a2e6fa4 189 }
IanBenzMaxim 6:a8c83a2e6fa4 190 uint_least8_t length;
IanBenzMaxim 6:a8c83a2e6fa4 191 result = master->readByte(I2CMaster::Ack, length);
IanBenzMaxim 6:a8c83a2e6fa4 192 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 193 master->stop();
IanBenzMaxim 6:a8c83a2e6fa4 194 return result;
IanBenzMaxim 6:a8c83a2e6fa4 195 }
IanBenzMaxim 6:a8c83a2e6fa4 196 if (length > response.size()) {
IanBenzMaxim 6:a8c83a2e6fa4 197 master->stop();
IanBenzMaxim 6:a8c83a2e6fa4 198 return make_error_code(InvalidResponseError);
IanBenzMaxim 6:a8c83a2e6fa4 199 }
IanBenzMaxim 6:a8c83a2e6fa4 200 response = response.first(length);
IanBenzMaxim 6:a8c83a2e6fa4 201 result = master->readBlock(I2CMaster::Nack, response);
IanBenzMaxim 6:a8c83a2e6fa4 202 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 203 master->stop();
IanBenzMaxim 6:a8c83a2e6fa4 204 return result;
IanBenzMaxim 6:a8c83a2e6fa4 205 }
IanBenzMaxim 6:a8c83a2e6fa4 206 result = master->stop();
IanBenzMaxim 6:a8c83a2e6fa4 207 return result;
IanBenzMaxim 6:a8c83a2e6fa4 208 }
IanBenzMaxim 6:a8c83a2e6fa4 209
IanBenzMaxim 6:a8c83a2e6fa4 210 } // namespace MaximInterface