BERG Cloud / BERGCloud

Dependents:   LittleCounter-Example

Committer:
nickludlam
Date:
Wed Apr 16 14:38:12 2014 +0000
Revision:
6:79100379d4b4
Parent:
5:2e04a8b3fc25
Updated to support the Berg V2 API. Please see http://bergcloud.com/devcenter/api/v2/device-v2 for more details.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nickludlam 0:b4ccb530b9eb 1 /*
nickludlam 0:b4ccb530b9eb 2
nickludlam 0:b4ccb530b9eb 3 BERGCloud library common API
nickludlam 0:b4ccb530b9eb 4
nickludlam 0:b4ccb530b9eb 5 Copyright (c) 2013 BERG Cloud Ltd. http://bergcloud.com/
nickludlam 0:b4ccb530b9eb 6
nickludlam 0:b4ccb530b9eb 7 Permission is hereby granted, free of charge, to any person obtaining a copy
nickludlam 0:b4ccb530b9eb 8 of this software and associated documentation files (the "Software"), to deal
nickludlam 0:b4ccb530b9eb 9 in the Software without restriction, including without limitation the rights
nickludlam 0:b4ccb530b9eb 10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
nickludlam 0:b4ccb530b9eb 11 copies of the Software, and to permit persons to whom the Software is
nickludlam 0:b4ccb530b9eb 12 furnished to do so, subject to the following conditions:
nickludlam 0:b4ccb530b9eb 13
nickludlam 0:b4ccb530b9eb 14 The above copyright notice and this permission notice shall be included in
nickludlam 0:b4ccb530b9eb 15 all copies or substantial portions of the Software.
nickludlam 0:b4ccb530b9eb 16
nickludlam 0:b4ccb530b9eb 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
nickludlam 0:b4ccb530b9eb 18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
nickludlam 0:b4ccb530b9eb 19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
nickludlam 0:b4ccb530b9eb 20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
nickludlam 0:b4ccb530b9eb 21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
nickludlam 0:b4ccb530b9eb 22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
nickludlam 0:b4ccb530b9eb 23 THE SOFTWARE.
nickludlam 0:b4ccb530b9eb 24
nickludlam 0:b4ccb530b9eb 25 */
nickludlam 0:b4ccb530b9eb 26
nickludlam 0:b4ccb530b9eb 27
nickludlam 0:b4ccb530b9eb 28 #define __STDC_LIMIT_MACROS /* Include C99 stdint defines in C++ code */
nickludlam 0:b4ccb530b9eb 29 #include <stdint.h>
nickludlam 0:b4ccb530b9eb 30 #include <stddef.h>
nickludlam 6:79100379d4b4 31 #include <string.h> /* For memset() */
nickludlam 0:b4ccb530b9eb 32
nickludlam 0:b4ccb530b9eb 33 #include "BERGCloudBase.h"
nickludlam 0:b4ccb530b9eb 34
nickludlam 0:b4ccb530b9eb 35 #define SPI_POLL_TIMEOUT_MS 1000
nickludlam 0:b4ccb530b9eb 36 #define SPI_SYNC_TIMEOUT_MS 10000
nickludlam 0:b4ccb530b9eb 37
nickludlam 0:b4ccb530b9eb 38 #define CONNECT_POLL_RATE_MS 250
nickludlam 0:b4ccb530b9eb 39
nickludlam 6:79100379d4b4 40 /* MessagePack for named commands and events */
nickludlam 6:79100379d4b4 41 #define _MP_FIXRAW_MIN 0xa0
nickludlam 6:79100379d4b4 42 #define _MP_FIXRAW_MAX 0xbf
nickludlam 6:79100379d4b4 43 #define _MAX_FIXRAW (_MP_FIXRAW_MAX - _MP_FIXRAW_MIN)
nickludlam 6:79100379d4b4 44
nickludlam 4:5a04c00b5b6f 45 uint8_t BERGCloudBase::nullKey[BC_KEY_SIZE_BYTES] = {0};
nickludlam 0:b4ccb530b9eb 46
nickludlam 5:2e04a8b3fc25 47 bool BERGCloudBase::_transaction(_BC_SPI_TRANSACTION *tr)
nickludlam 0:b4ccb530b9eb 48 {
nickludlam 0:b4ccb530b9eb 49 uint16_t i, j;
nickludlam 0:b4ccb530b9eb 50 uint8_t rxByte;
nickludlam 0:b4ccb530b9eb 51 bool timeout;
nickludlam 0:b4ccb530b9eb 52 uint8_t dataSize;
nickludlam 0:b4ccb530b9eb 53 uint16_t groupSize;
nickludlam 0:b4ccb530b9eb 54 uint16_t dataCRC;
nickludlam 0:b4ccb530b9eb 55 uint16_t calcCRC;
nickludlam 0:b4ccb530b9eb 56 uint8_t header[SPI_HEADER_SIZE_BYTES];
nickludlam 0:b4ccb530b9eb 57 uint8_t footer[SPI_FOOTER_SIZE_BYTES];
nickludlam 0:b4ccb530b9eb 58
nickludlam 0:b4ccb530b9eb 59 /* Check synchronisation */
nickludlam 0:b4ccb530b9eb 60 if (!synced)
nickludlam 0:b4ccb530b9eb 61 {
nickludlam 0:b4ccb530b9eb 62 timerReset();
nickludlam 0:b4ccb530b9eb 63
nickludlam 0:b4ccb530b9eb 64 do {
nickludlam 0:b4ccb530b9eb 65 rxByte = SPITransaction(SPI_PROTOCOL_PAD, true);
nickludlam 0:b4ccb530b9eb 66 timeout = timerRead_mS() > SPI_SYNC_TIMEOUT_MS;
nickludlam 0:b4ccb530b9eb 67
nickludlam 0:b4ccb530b9eb 68 } while ((rxByte != SPI_PROTOCOL_RESET) && !timeout);
nickludlam 0:b4ccb530b9eb 69
nickludlam 0:b4ccb530b9eb 70 if (timeout)
nickludlam 0:b4ccb530b9eb 71 {
nickludlam 0:b4ccb530b9eb 72 _LOG("Timeout, sync (BERGCloudBase::transaction)\r\n");
nickludlam 0:b4ccb530b9eb 73 return false;
nickludlam 0:b4ccb530b9eb 74 }
nickludlam 0:b4ccb530b9eb 75
nickludlam 0:b4ccb530b9eb 76 /* Resynchronisation successful */
nickludlam 0:b4ccb530b9eb 77 synced = true;
nickludlam 0:b4ccb530b9eb 78 }
nickludlam 0:b4ccb530b9eb 79
nickludlam 0:b4ccb530b9eb 80 /* Calculate total data size */
nickludlam 0:b4ccb530b9eb 81 dataSize = 0;
nickludlam 0:b4ccb530b9eb 82
nickludlam 0:b4ccb530b9eb 83 for (i=0; i<_TX_GROUPS; i++)
nickludlam 0:b4ccb530b9eb 84 {
nickludlam 0:b4ccb530b9eb 85 dataSize += tr->tx[i].dataSize;
nickludlam 0:b4ccb530b9eb 86 }
nickludlam 0:b4ccb530b9eb 87
nickludlam 0:b4ccb530b9eb 88 /* Initialise CRC */
nickludlam 0:b4ccb530b9eb 89 calcCRC = 0xffff;
nickludlam 0:b4ccb530b9eb 90
nickludlam 0:b4ccb530b9eb 91 /* Create header */
nickludlam 0:b4ccb530b9eb 92 header[0] = tr->command;
nickludlam 0:b4ccb530b9eb 93 header[1] = 0x00; /* Reserved */
nickludlam 0:b4ccb530b9eb 94 header[2] = 0x00; /* Reserved */
nickludlam 0:b4ccb530b9eb 95 header[3] = dataSize;
nickludlam 0:b4ccb530b9eb 96
nickludlam 0:b4ccb530b9eb 97 /* Send header */
nickludlam 0:b4ccb530b9eb 98 for (i=0; i<sizeof(header); i++)
nickludlam 0:b4ccb530b9eb 99 {
nickludlam 0:b4ccb530b9eb 100
nickludlam 0:b4ccb530b9eb 101 calcCRC = Crc16(header[i], calcCRC);
nickludlam 0:b4ccb530b9eb 102 rxByte = SPITransaction(header[i], false);
nickludlam 0:b4ccb530b9eb 103
nickludlam 0:b4ccb530b9eb 104 if (rxByte == SPI_PROTOCOL_RESET)
nickludlam 0:b4ccb530b9eb 105 {
nickludlam 0:b4ccb530b9eb 106 _LOG("Reset, send header (BERGCloudBase::transaction)\r\n");
nickludlam 0:b4ccb530b9eb 107 return false;
nickludlam 0:b4ccb530b9eb 108 }
nickludlam 0:b4ccb530b9eb 109
nickludlam 0:b4ccb530b9eb 110 if (rxByte != SPI_PROTOCOL_PAD)
nickludlam 0:b4ccb530b9eb 111 {
nickludlam 0:b4ccb530b9eb 112 _LOG("SyncErr, send header (BERGCloudBase::transaction)\r\n");
nickludlam 0:b4ccb530b9eb 113 synced = false;
nickludlam 0:b4ccb530b9eb 114 return false;
nickludlam 0:b4ccb530b9eb 115 }
nickludlam 0:b4ccb530b9eb 116 }
nickludlam 0:b4ccb530b9eb 117
nickludlam 0:b4ccb530b9eb 118 /* Send data groups */
nickludlam 0:b4ccb530b9eb 119 for (i=0; i<_TX_GROUPS; i++)
nickludlam 0:b4ccb530b9eb 120 {
nickludlam 0:b4ccb530b9eb 121 for (j=0; j<tr->tx[i].dataSize; j++)
nickludlam 0:b4ccb530b9eb 122 {
nickludlam 0:b4ccb530b9eb 123 calcCRC = Crc16(tr->tx[i].buffer[j], calcCRC);
nickludlam 0:b4ccb530b9eb 124 rxByte = SPITransaction(tr->tx[i].buffer[j], false);
nickludlam 0:b4ccb530b9eb 125
nickludlam 0:b4ccb530b9eb 126 if (rxByte == SPI_PROTOCOL_RESET)
nickludlam 0:b4ccb530b9eb 127 {
nickludlam 0:b4ccb530b9eb 128 _LOG("Reset, send data (BERGCloudBase::transaction)\r\n");
nickludlam 0:b4ccb530b9eb 129 return false;
nickludlam 0:b4ccb530b9eb 130 }
nickludlam 0:b4ccb530b9eb 131
nickludlam 0:b4ccb530b9eb 132 if (rxByte != SPI_PROTOCOL_PAD)
nickludlam 0:b4ccb530b9eb 133 {
nickludlam 0:b4ccb530b9eb 134 _LOG("SyncErr, send data (BERGCloudBase::transaction)\r\n");
nickludlam 0:b4ccb530b9eb 135 synced = false;
nickludlam 0:b4ccb530b9eb 136 return false;
nickludlam 0:b4ccb530b9eb 137 }
nickludlam 0:b4ccb530b9eb 138 }
nickludlam 0:b4ccb530b9eb 139 }
nickludlam 0:b4ccb530b9eb 140
nickludlam 0:b4ccb530b9eb 141 /* Create footer */
nickludlam 0:b4ccb530b9eb 142 footer[0] = calcCRC >> 8;
nickludlam 0:b4ccb530b9eb 143 footer[1] = calcCRC & 0xff;
nickludlam 0:b4ccb530b9eb 144
nickludlam 0:b4ccb530b9eb 145 /* Send footer */
nickludlam 0:b4ccb530b9eb 146 for (i=0; i<sizeof(footer); i++)
nickludlam 0:b4ccb530b9eb 147 {
nickludlam 0:b4ccb530b9eb 148 rxByte = SPITransaction(footer[i], false);
nickludlam 0:b4ccb530b9eb 149
nickludlam 0:b4ccb530b9eb 150 if (rxByte == SPI_PROTOCOL_RESET)
nickludlam 0:b4ccb530b9eb 151 {
nickludlam 0:b4ccb530b9eb 152 _LOG("Reset, send footer (BERGCloudBase::transaction)\r\n");
nickludlam 0:b4ccb530b9eb 153 return false;
nickludlam 0:b4ccb530b9eb 154 }
nickludlam 0:b4ccb530b9eb 155
nickludlam 0:b4ccb530b9eb 156 if (rxByte != SPI_PROTOCOL_PAD)
nickludlam 0:b4ccb530b9eb 157 {
nickludlam 0:b4ccb530b9eb 158 _LOG("SyncErr, send footer (BERGCloudBase::transaction)\r\n");
nickludlam 0:b4ccb530b9eb 159 synced = false;
nickludlam 0:b4ccb530b9eb 160 return false;
nickludlam 0:b4ccb530b9eb 161 }
nickludlam 0:b4ccb530b9eb 162 }
nickludlam 0:b4ccb530b9eb 163
nickludlam 0:b4ccb530b9eb 164 /* Poll for response */
nickludlam 0:b4ccb530b9eb 165 timerReset();
nickludlam 0:b4ccb530b9eb 166
nickludlam 0:b4ccb530b9eb 167 do {
nickludlam 0:b4ccb530b9eb 168 rxByte = SPITransaction(SPI_PROTOCOL_PAD, false);
nickludlam 0:b4ccb530b9eb 169
nickludlam 0:b4ccb530b9eb 170 if (rxByte == SPI_PROTOCOL_RESET)
nickludlam 0:b4ccb530b9eb 171 {
nickludlam 0:b4ccb530b9eb 172 _LOG("Reset, poll (BERGCloudBase::transaction)\r\n");
nickludlam 0:b4ccb530b9eb 173 return false;
nickludlam 0:b4ccb530b9eb 174 }
nickludlam 0:b4ccb530b9eb 175
nickludlam 0:b4ccb530b9eb 176 if (rxByte == SPI_PROTOCOL_PENDING)
nickludlam 0:b4ccb530b9eb 177 {
nickludlam 0:b4ccb530b9eb 178 /* Waiting for data; reset timeout */
nickludlam 0:b4ccb530b9eb 179 timerReset();
nickludlam 0:b4ccb530b9eb 180 }
nickludlam 0:b4ccb530b9eb 181
nickludlam 0:b4ccb530b9eb 182 timeout = timerRead_mS() > SPI_POLL_TIMEOUT_MS;
nickludlam 0:b4ccb530b9eb 183
nickludlam 0:b4ccb530b9eb 184 } while (((rxByte == SPI_PROTOCOL_PAD) || (rxByte == SPI_PROTOCOL_PENDING)) && !timeout);
nickludlam 0:b4ccb530b9eb 185
nickludlam 0:b4ccb530b9eb 186 if (timeout)
nickludlam 0:b4ccb530b9eb 187 {
nickludlam 0:b4ccb530b9eb 188 _LOG("Timeout, poll (BERGCloudBase::transaction)\r\n");
nickludlam 0:b4ccb530b9eb 189 synced = false;
nickludlam 0:b4ccb530b9eb 190 return false;
nickludlam 0:b4ccb530b9eb 191 }
nickludlam 0:b4ccb530b9eb 192
nickludlam 0:b4ccb530b9eb 193 /* Initialise CRC */
nickludlam 0:b4ccb530b9eb 194 calcCRC = 0xffff;
nickludlam 0:b4ccb530b9eb 195
nickludlam 0:b4ccb530b9eb 196 /* Read header, we already have the first byte */
nickludlam 0:b4ccb530b9eb 197 header[0] = rxByte;
nickludlam 0:b4ccb530b9eb 198 calcCRC = Crc16(header[0], calcCRC);
nickludlam 0:b4ccb530b9eb 199
nickludlam 0:b4ccb530b9eb 200 for (i=1; i < SPI_HEADER_SIZE_BYTES; i++)
nickludlam 0:b4ccb530b9eb 201 {
nickludlam 0:b4ccb530b9eb 202 header[i] = SPITransaction(SPI_PROTOCOL_PAD, false);
nickludlam 0:b4ccb530b9eb 203 calcCRC = Crc16(header[i], calcCRC);
nickludlam 0:b4ccb530b9eb 204 }
nickludlam 0:b4ccb530b9eb 205
nickludlam 0:b4ccb530b9eb 206 /* Get data size */
nickludlam 0:b4ccb530b9eb 207 dataSize = header[3];
nickludlam 0:b4ccb530b9eb 208
nickludlam 0:b4ccb530b9eb 209 /* Read data groups */
nickludlam 0:b4ccb530b9eb 210 for (i=0; i<_RX_GROUPS; i++)
nickludlam 0:b4ccb530b9eb 211 {
nickludlam 0:b4ccb530b9eb 212 groupSize = tr->rx[i].bufferSize;
nickludlam 0:b4ccb530b9eb 213 j = 0; /* Start of the group buffer */
nickludlam 0:b4ccb530b9eb 214
nickludlam 0:b4ccb530b9eb 215 while((dataSize > 0) && (groupSize > 0))
nickludlam 0:b4ccb530b9eb 216 {
nickludlam 0:b4ccb530b9eb 217 tr->rx[i].buffer[j] = SPITransaction(SPI_PROTOCOL_PAD, false);
nickludlam 0:b4ccb530b9eb 218 calcCRC = Crc16(tr->rx[i].buffer[j], calcCRC);
nickludlam 0:b4ccb530b9eb 219
nickludlam 0:b4ccb530b9eb 220 /* Next */
nickludlam 0:b4ccb530b9eb 221 j++;
nickludlam 0:b4ccb530b9eb 222
nickludlam 0:b4ccb530b9eb 223 /* Update the total data remaining and the space remaining in this group. */
nickludlam 0:b4ccb530b9eb 224 dataSize--;
nickludlam 0:b4ccb530b9eb 225 groupSize--;
nickludlam 0:b4ccb530b9eb 226 }
nickludlam 0:b4ccb530b9eb 227
nickludlam 0:b4ccb530b9eb 228 if (tr->rx[i].dataSize != NULL)
nickludlam 0:b4ccb530b9eb 229 {
nickludlam 0:b4ccb530b9eb 230 /* Return the number of bytes used in this buffer */
nickludlam 0:b4ccb530b9eb 231 *tr->rx[i].dataSize = tr->rx[i].bufferSize - groupSize;
nickludlam 0:b4ccb530b9eb 232 }
nickludlam 0:b4ccb530b9eb 233 }
nickludlam 0:b4ccb530b9eb 234
nickludlam 0:b4ccb530b9eb 235 if (dataSize > 0)
nickludlam 0:b4ccb530b9eb 236 {
nickludlam 0:b4ccb530b9eb 237 /* Too much data sent */
nickludlam 0:b4ccb530b9eb 238 _LOG("SizeErr, read data (BERGCloudBase::transaction)\r\n");
nickludlam 0:b4ccb530b9eb 239 synced = false;
nickludlam 0:b4ccb530b9eb 240 return false;
nickludlam 0:b4ccb530b9eb 241 }
nickludlam 0:b4ccb530b9eb 242
nickludlam 0:b4ccb530b9eb 243 /* Read CRC; set nCS high */
nickludlam 0:b4ccb530b9eb 244 dataCRC = SPITransaction(SPI_PROTOCOL_PAD, false); /* MSByte */
nickludlam 0:b4ccb530b9eb 245 dataCRC <<= 8;
nickludlam 0:b4ccb530b9eb 246 dataCRC |= SPITransaction(SPI_PROTOCOL_PAD, true /* nCS -> high */); /* LSByte */
nickludlam 0:b4ccb530b9eb 247
nickludlam 0:b4ccb530b9eb 248 /* Compare with calculated CRC */
nickludlam 0:b4ccb530b9eb 249 if (calcCRC != dataCRC)
nickludlam 0:b4ccb530b9eb 250 {
nickludlam 0:b4ccb530b9eb 251 /* Invalid CRC */
nickludlam 0:b4ccb530b9eb 252 _LOG("CRCErr, read data (BERGCloudBase::transaction)\r\n");
nickludlam 0:b4ccb530b9eb 253 synced = false;
nickludlam 0:b4ccb530b9eb 254 return false;
nickludlam 0:b4ccb530b9eb 255 }
nickludlam 0:b4ccb530b9eb 256
nickludlam 0:b4ccb530b9eb 257 /* Get reponse code */
nickludlam 0:b4ccb530b9eb 258 lastResponse = header[0];
nickludlam 0:b4ccb530b9eb 259
nickludlam 0:b4ccb530b9eb 260 return (lastResponse == SPI_RSP_SUCCESS);
nickludlam 0:b4ccb530b9eb 261 }
nickludlam 0:b4ccb530b9eb 262
nickludlam 5:2e04a8b3fc25 263 bool BERGCloudBase::transaction(_BC_SPI_TRANSACTION *tr)
nickludlam 5:2e04a8b3fc25 264 {
nickludlam 5:2e04a8b3fc25 265 bool result;
nickludlam 5:2e04a8b3fc25 266
nickludlam 5:2e04a8b3fc25 267 /* For thread synchronisation */
nickludlam 5:2e04a8b3fc25 268 lockTake();
nickludlam 5:2e04a8b3fc25 269 result = _transaction(tr);
nickludlam 5:2e04a8b3fc25 270 lockRelease();
nickludlam 5:2e04a8b3fc25 271
nickludlam 5:2e04a8b3fc25 272 return result;
nickludlam 5:2e04a8b3fc25 273 }
nickludlam 5:2e04a8b3fc25 274
nickludlam 0:b4ccb530b9eb 275 void BERGCloudBase::initTransaction(_BC_SPI_TRANSACTION *tr)
nickludlam 0:b4ccb530b9eb 276 {
nickludlam 0:b4ccb530b9eb 277 memset(tr, 0x00, sizeof(_BC_SPI_TRANSACTION));
nickludlam 0:b4ccb530b9eb 278 }
nickludlam 0:b4ccb530b9eb 279
nickludlam 0:b4ccb530b9eb 280 bool BERGCloudBase::pollForCommand(uint8_t *commandBuffer, uint16_t commandBufferSize, uint16_t& commandSize, uint8_t& commandID)
nickludlam 0:b4ccb530b9eb 281 {
nickludlam 0:b4ccb530b9eb 282 /* Returns TRUE if a valid command has been received */
nickludlam 0:b4ccb530b9eb 283
nickludlam 6:79100379d4b4 284 _LOG("pollForCommand() methods returning a command ID number have been deprecated.\r\n");
nickludlam 6:79100379d4b4 285
nickludlam 0:b4ccb530b9eb 286 _BC_SPI_TRANSACTION tr;
nickludlam 0:b4ccb530b9eb 287 uint8_t cmdID[2] = {0};
nickludlam 0:b4ccb530b9eb 288 uint16_t cmdIDSize = 0;
nickludlam 0:b4ccb530b9eb 289
nickludlam 0:b4ccb530b9eb 290 initTransaction(&tr);
nickludlam 0:b4ccb530b9eb 291
nickludlam 0:b4ccb530b9eb 292 tr.command = SPI_CMD_POLL_FOR_COMMAND;
nickludlam 0:b4ccb530b9eb 293
nickludlam 0:b4ccb530b9eb 294 tr.rx[0].buffer = cmdID;
nickludlam 0:b4ccb530b9eb 295 tr.rx[0].bufferSize = sizeof(cmdID);
nickludlam 0:b4ccb530b9eb 296 tr.rx[0].dataSize = &cmdIDSize;
nickludlam 0:b4ccb530b9eb 297
nickludlam 0:b4ccb530b9eb 298 tr.rx[1].buffer = commandBuffer;
nickludlam 0:b4ccb530b9eb 299 tr.rx[1].bufferSize = commandBufferSize;
nickludlam 0:b4ccb530b9eb 300 tr.rx[1].dataSize = &commandSize;
nickludlam 0:b4ccb530b9eb 301
nickludlam 0:b4ccb530b9eb 302 if (transaction(&tr))
nickludlam 0:b4ccb530b9eb 303 {
nickludlam 0:b4ccb530b9eb 304 commandID = cmdID[1];
nickludlam 0:b4ccb530b9eb 305 return true;
nickludlam 0:b4ccb530b9eb 306 }
nickludlam 0:b4ccb530b9eb 307
nickludlam 0:b4ccb530b9eb 308 commandID = 0;
nickludlam 0:b4ccb530b9eb 309 commandSize = 0;
nickludlam 0:b4ccb530b9eb 310 return false;
nickludlam 0:b4ccb530b9eb 311 }
nickludlam 0:b4ccb530b9eb 312
nickludlam 6:79100379d4b4 313 bool BERGCloudBase::pollForCommand(uint8_t *commandBuffer, uint16_t commandBufferSize, uint16_t& commandSize, char *commandName, uint8_t commandNameMaxSize)
nickludlam 6:79100379d4b4 314 {
nickludlam 6:79100379d4b4 315 /* Returns TRUE if a valid command has been received */
nickludlam 6:79100379d4b4 316
nickludlam 6:79100379d4b4 317 _BC_SPI_TRANSACTION tr;
nickludlam 6:79100379d4b4 318 uint8_t cmdID[2] = {0};
nickludlam 6:79100379d4b4 319 uint16_t cmdIDSize = 0;
nickludlam 6:79100379d4b4 320 uint8_t commandNameSize;
nickludlam 6:79100379d4b4 321 uint8_t originalCommandNameSize;
nickludlam 6:79100379d4b4 322 uint8_t msgPackByte;
nickludlam 6:79100379d4b4 323 uint16_t command;
nickludlam 6:79100379d4b4 324
nickludlam 6:79100379d4b4 325 if ((commandName == NULL) || (commandNameMaxSize < 2))
nickludlam 6:79100379d4b4 326 {
nickludlam 6:79100379d4b4 327 return false;
nickludlam 6:79100379d4b4 328 }
nickludlam 6:79100379d4b4 329
nickludlam 6:79100379d4b4 330 initTransaction(&tr);
nickludlam 6:79100379d4b4 331
nickludlam 6:79100379d4b4 332 tr.command = SPI_CMD_POLL_FOR_COMMAND;
nickludlam 6:79100379d4b4 333
nickludlam 6:79100379d4b4 334 tr.rx[0].buffer = cmdID;
nickludlam 6:79100379d4b4 335 tr.rx[0].bufferSize = sizeof(cmdID);
nickludlam 6:79100379d4b4 336 tr.rx[0].dataSize = &cmdIDSize;
nickludlam 6:79100379d4b4 337
nickludlam 6:79100379d4b4 338 tr.rx[1].buffer = commandBuffer;
nickludlam 6:79100379d4b4 339 tr.rx[1].bufferSize = commandBufferSize;
nickludlam 6:79100379d4b4 340 tr.rx[1].dataSize = &commandSize;
nickludlam 6:79100379d4b4 341
nickludlam 6:79100379d4b4 342 if (transaction(&tr))
nickludlam 6:79100379d4b4 343 {
nickludlam 6:79100379d4b4 344 command = (cmdID[0] << 8) | cmdID[1];
nickludlam 6:79100379d4b4 345 if (command == BC_COMMAND_NAMED_PACKED)
nickludlam 6:79100379d4b4 346 {
nickludlam 6:79100379d4b4 347 /* Get command name string size */
nickludlam 6:79100379d4b4 348 msgPackByte = *commandBuffer;
nickludlam 6:79100379d4b4 349
nickludlam 6:79100379d4b4 350 if ((msgPackByte <_MP_FIXRAW_MIN) || (msgPackByte > _MP_FIXRAW_MAX))
nickludlam 6:79100379d4b4 351 {
nickludlam 6:79100379d4b4 352 /* Invalid */
nickludlam 6:79100379d4b4 353 return false;
nickludlam 6:79100379d4b4 354 }
nickludlam 6:79100379d4b4 355
nickludlam 6:79100379d4b4 356 commandNameSize = originalCommandNameSize = msgPackByte - _MP_FIXRAW_MIN;
nickludlam 6:79100379d4b4 357
nickludlam 6:79100379d4b4 358 /* Limit to the size of the buffer provided */
nickludlam 6:79100379d4b4 359 if (commandNameSize > (commandNameMaxSize-1)) /* -1 for null terminator */
nickludlam 6:79100379d4b4 360 {
nickludlam 6:79100379d4b4 361 commandNameSize = (commandNameMaxSize-1);
nickludlam 6:79100379d4b4 362 }
nickludlam 6:79100379d4b4 363
nickludlam 6:79100379d4b4 364 /* Copy command name string as a null-terminated C string */
nickludlam 6:79100379d4b4 365 bytecpy((uint8_t *)commandName, (commandBuffer+1), commandNameSize); /* +1 for messagePack fixraw byte */
nickludlam 6:79100379d4b4 366 commandName[commandNameSize] = '\0';
nickludlam 6:79100379d4b4 367
nickludlam 6:79100379d4b4 368 /* Move up remaining packed data, update size */
nickludlam 6:79100379d4b4 369 commandSize -= (originalCommandNameSize + 1); /* +1 for messagePack fixraw byte */
nickludlam 6:79100379d4b4 370 bytecpy(commandBuffer, commandBuffer + (originalCommandNameSize + 1), commandSize);
nickludlam 6:79100379d4b4 371 return true;
nickludlam 6:79100379d4b4 372 }
nickludlam 6:79100379d4b4 373 }
nickludlam 6:79100379d4b4 374
nickludlam 6:79100379d4b4 375 *commandName = '\0';
nickludlam 6:79100379d4b4 376 commandSize = 0;
nickludlam 6:79100379d4b4 377 return false;
nickludlam 6:79100379d4b4 378 }
nickludlam 6:79100379d4b4 379
nickludlam 0:b4ccb530b9eb 380 #ifdef BERGCLOUD_PACK_UNPACK
nickludlam 0:b4ccb530b9eb 381 bool BERGCloudBase::pollForCommand(BERGCloudMessageBuffer& buffer, uint8_t& commandID)
nickludlam 0:b4ccb530b9eb 382 {
nickludlam 0:b4ccb530b9eb 383 /* Returns TRUE if a valid command has been received */
nickludlam 0:b4ccb530b9eb 384
nickludlam 6:79100379d4b4 385 _LOG("pollForCommand() methods returning a command ID number have been deprecated.\r\n");
nickludlam 6:79100379d4b4 386
nickludlam 0:b4ccb530b9eb 387 _BC_SPI_TRANSACTION tr;
nickludlam 0:b4ccb530b9eb 388 uint8_t cmdID[2] = {0};
nickludlam 0:b4ccb530b9eb 389 uint16_t cmdIDSize = 0;
nickludlam 0:b4ccb530b9eb 390 uint16_t dataSize = 0;
nickludlam 0:b4ccb530b9eb 391
nickludlam 0:b4ccb530b9eb 392 initTransaction(&tr);
nickludlam 0:b4ccb530b9eb 393 buffer.clear();
nickludlam 0:b4ccb530b9eb 394
nickludlam 0:b4ccb530b9eb 395 tr.command = SPI_CMD_POLL_FOR_COMMAND;
nickludlam 0:b4ccb530b9eb 396
nickludlam 0:b4ccb530b9eb 397 tr.rx[0].buffer = cmdID;
nickludlam 0:b4ccb530b9eb 398 tr.rx[0].bufferSize = sizeof(cmdID);
nickludlam 0:b4ccb530b9eb 399 tr.rx[0].dataSize = &cmdIDSize;
nickludlam 0:b4ccb530b9eb 400
nickludlam 0:b4ccb530b9eb 401 tr.rx[1].buffer = buffer.ptr();
nickludlam 0:b4ccb530b9eb 402 tr.rx[1].bufferSize = buffer.size();
nickludlam 0:b4ccb530b9eb 403 tr.rx[1].dataSize = &dataSize;
nickludlam 0:b4ccb530b9eb 404
nickludlam 0:b4ccb530b9eb 405 if (transaction(&tr))
nickludlam 0:b4ccb530b9eb 406 {
nickludlam 0:b4ccb530b9eb 407 commandID = cmdID[1];
nickludlam 0:b4ccb530b9eb 408 buffer.used(dataSize);
nickludlam 0:b4ccb530b9eb 409 return true;
nickludlam 0:b4ccb530b9eb 410 }
nickludlam 0:b4ccb530b9eb 411
nickludlam 0:b4ccb530b9eb 412 commandID = 0;
nickludlam 0:b4ccb530b9eb 413 buffer.used(0);
nickludlam 0:b4ccb530b9eb 414 return false;
nickludlam 0:b4ccb530b9eb 415 }
nickludlam 6:79100379d4b4 416
nickludlam 6:79100379d4b4 417 bool BERGCloudBase::pollForCommand(BERGCloudMessageBuffer& buffer, char *commandName, uint8_t commandNameMaxSize)
nickludlam 6:79100379d4b4 418 {
nickludlam 6:79100379d4b4 419 /* Returns TRUE if a valid command has been received */
nickludlam 6:79100379d4b4 420
nickludlam 6:79100379d4b4 421 _BC_SPI_TRANSACTION tr;
nickludlam 6:79100379d4b4 422 uint8_t cmdID[2] = {0};
nickludlam 6:79100379d4b4 423 uint16_t cmdIDSize = 0;
nickludlam 6:79100379d4b4 424 uint16_t dataSize = 0;
nickludlam 6:79100379d4b4 425 uint8_t commandNameSize;
nickludlam 6:79100379d4b4 426 uint8_t originalCommandNameSize;
nickludlam 6:79100379d4b4 427 uint8_t msgPackByte;
nickludlam 6:79100379d4b4 428 uint16_t command;
nickludlam 6:79100379d4b4 429
nickludlam 6:79100379d4b4 430 if ((commandName == NULL) || (commandNameMaxSize < 2))
nickludlam 6:79100379d4b4 431 {
nickludlam 6:79100379d4b4 432 return false;
nickludlam 6:79100379d4b4 433 }
nickludlam 6:79100379d4b4 434
nickludlam 6:79100379d4b4 435 initTransaction(&tr);
nickludlam 6:79100379d4b4 436 buffer.clear();
nickludlam 6:79100379d4b4 437
nickludlam 6:79100379d4b4 438 tr.command = SPI_CMD_POLL_FOR_COMMAND;
nickludlam 6:79100379d4b4 439
nickludlam 6:79100379d4b4 440 tr.rx[0].buffer = cmdID;
nickludlam 6:79100379d4b4 441 tr.rx[0].bufferSize = sizeof(cmdID);
nickludlam 6:79100379d4b4 442 tr.rx[0].dataSize = &cmdIDSize;
nickludlam 6:79100379d4b4 443
nickludlam 6:79100379d4b4 444 tr.rx[1].buffer = buffer.ptr();
nickludlam 6:79100379d4b4 445 tr.rx[1].bufferSize = buffer.size();
nickludlam 6:79100379d4b4 446 tr.rx[1].dataSize = &dataSize;
nickludlam 6:79100379d4b4 447
nickludlam 6:79100379d4b4 448 if (transaction(&tr))
nickludlam 6:79100379d4b4 449 {
nickludlam 6:79100379d4b4 450 command = (cmdID[0] << 8) | cmdID[1];
nickludlam 6:79100379d4b4 451 if (command == BC_COMMAND_NAMED_PACKED)
nickludlam 6:79100379d4b4 452 {
nickludlam 6:79100379d4b4 453 /* Get command name string size */
nickludlam 6:79100379d4b4 454 msgPackByte = *buffer.ptr();
nickludlam 6:79100379d4b4 455
nickludlam 6:79100379d4b4 456 if ((msgPackByte <_MP_FIXRAW_MIN) || (msgPackByte > _MP_FIXRAW_MAX))
nickludlam 6:79100379d4b4 457 {
nickludlam 6:79100379d4b4 458 /* Invalid */
nickludlam 6:79100379d4b4 459 return false;
nickludlam 6:79100379d4b4 460 }
nickludlam 6:79100379d4b4 461
nickludlam 6:79100379d4b4 462 commandNameSize = originalCommandNameSize = msgPackByte - _MP_FIXRAW_MIN;
nickludlam 6:79100379d4b4 463
nickludlam 6:79100379d4b4 464 /* Limit to the size of the buffer provided */
nickludlam 6:79100379d4b4 465 if (commandNameSize > (commandNameMaxSize-1)) /* -1 for null terminator */
nickludlam 6:79100379d4b4 466 {
nickludlam 6:79100379d4b4 467 commandNameSize = (commandNameMaxSize-1);
nickludlam 6:79100379d4b4 468 }
nickludlam 6:79100379d4b4 469
nickludlam 6:79100379d4b4 470 /* Copy command name string as a null-terminated C string */
nickludlam 6:79100379d4b4 471 bytecpy((uint8_t *)commandName, (buffer.ptr()+1), commandNameSize); /* +1 for messagePack fixraw byte */
nickludlam 6:79100379d4b4 472 commandName[commandNameSize] = '\0';
nickludlam 6:79100379d4b4 473
nickludlam 6:79100379d4b4 474 /* Move up remaining packed data, update size */
nickludlam 6:79100379d4b4 475 dataSize -= (originalCommandNameSize + 1); /* +1 for messagePack fixraw byte */
nickludlam 6:79100379d4b4 476 bytecpy(buffer.ptr(), buffer.ptr() + (originalCommandNameSize + 1), dataSize);
nickludlam 6:79100379d4b4 477
nickludlam 6:79100379d4b4 478 buffer.used(dataSize);
nickludlam 6:79100379d4b4 479 return true;
nickludlam 6:79100379d4b4 480 }
nickludlam 6:79100379d4b4 481 }
nickludlam 6:79100379d4b4 482
nickludlam 6:79100379d4b4 483 buffer.used(0);
nickludlam 6:79100379d4b4 484 *commandName = '\0';
nickludlam 6:79100379d4b4 485 return false;
nickludlam 6:79100379d4b4 486 }
nickludlam 0:b4ccb530b9eb 487 #endif
nickludlam 0:b4ccb530b9eb 488
nickludlam 0:b4ccb530b9eb 489 bool BERGCloudBase::_sendEvent(uint8_t eventCode, uint8_t *eventBuffer, uint16_t eventSize, uint8_t command)
nickludlam 0:b4ccb530b9eb 490 {
nickludlam 0:b4ccb530b9eb 491 /* Returns TRUE if the event is sent successfully */
nickludlam 0:b4ccb530b9eb 492
nickludlam 6:79100379d4b4 493 _LOG("sendEvent() methods using an eventCode number have been deprecated.\r\n");
nickludlam 6:79100379d4b4 494
nickludlam 0:b4ccb530b9eb 495 _BC_SPI_TRANSACTION tr;
nickludlam 0:b4ccb530b9eb 496 uint8_t header[4] = {0};
nickludlam 0:b4ccb530b9eb 497
nickludlam 0:b4ccb530b9eb 498 if (eventSize > (SPI_MAX_PAYLOAD_SIZE_BYTES - sizeof(header)))
nickludlam 0:b4ccb530b9eb 499 {
nickludlam 0:b4ccb530b9eb 500 /* Too big */
nickludlam 0:b4ccb530b9eb 501 return false;
nickludlam 0:b4ccb530b9eb 502 }
nickludlam 0:b4ccb530b9eb 503
nickludlam 0:b4ccb530b9eb 504 header[0] = eventCode;
nickludlam 0:b4ccb530b9eb 505
nickludlam 0:b4ccb530b9eb 506 initTransaction(&tr);
nickludlam 0:b4ccb530b9eb 507
nickludlam 0:b4ccb530b9eb 508 tr.command = command;
nickludlam 0:b4ccb530b9eb 509 tr.tx[0].buffer = (uint8_t *)header;
nickludlam 0:b4ccb530b9eb 510 tr.tx[0].dataSize = sizeof(header);
nickludlam 0:b4ccb530b9eb 511 tr.tx[1].buffer = eventBuffer;
nickludlam 0:b4ccb530b9eb 512 tr.tx[1].dataSize = (uint8_t)eventSize;
nickludlam 0:b4ccb530b9eb 513
nickludlam 0:b4ccb530b9eb 514 return transaction(&tr);
nickludlam 0:b4ccb530b9eb 515 }
nickludlam 0:b4ccb530b9eb 516
nickludlam 4:5a04c00b5b6f 517 bool BERGCloudBase::sendEvent(uint8_t eventCode, uint8_t *eventBuffer, uint16_t eventSize, bool packed)
nickludlam 0:b4ccb530b9eb 518 {
nickludlam 6:79100379d4b4 519
nickludlam 4:5a04c00b5b6f 520 return _sendEvent(eventCode, eventBuffer, eventSize, packed ? SPI_CMD_SEND_EVENT_PACKED : SPI_CMD_SEND_EVENT_RAW);
nickludlam 0:b4ccb530b9eb 521 }
nickludlam 0:b4ccb530b9eb 522
nickludlam 6:79100379d4b4 523 bool BERGCloudBase::sendEvent(const char *eventName, uint8_t *eventBuffer, uint16_t eventSize, bool packed)
nickludlam 6:79100379d4b4 524 {
nickludlam 6:79100379d4b4 525 /* Returns TRUE if the event is sent successfully */
nickludlam 6:79100379d4b4 526
nickludlam 6:79100379d4b4 527 _BC_SPI_TRANSACTION tr;
nickludlam 6:79100379d4b4 528 uint8_t headerSize = 5; /* Four bytes of SPI header, one byte of messagePack type */
nickludlam 6:79100379d4b4 529 uint8_t header[5 + _MAX_FIXRAW] = {0}; /* Header size plus maximum name string size */
nickludlam 6:79100379d4b4 530
nickludlam 6:79100379d4b4 531 if (!packed)
nickludlam 6:79100379d4b4 532 {
nickludlam 6:79100379d4b4 533 /* We only support packed data now */
nickludlam 6:79100379d4b4 534 return false;
nickludlam 6:79100379d4b4 535 }
nickludlam 6:79100379d4b4 536
nickludlam 6:79100379d4b4 537 if ((eventName == NULL) || (eventName[0] == '\0'))
nickludlam 6:79100379d4b4 538 {
nickludlam 6:79100379d4b4 539 _LOG("Event name must be at least one character.\r\n");
nickludlam 6:79100379d4b4 540 return false;
nickludlam 6:79100379d4b4 541 }
nickludlam 6:79100379d4b4 542
nickludlam 6:79100379d4b4 543 /* Create SPI header */
nickludlam 6:79100379d4b4 544 header[0] = BC_EVENT_NAMED_PACKED & BC_EVENT_ID_MASK;
nickludlam 6:79100379d4b4 545 header[1] = 0;
nickludlam 6:79100379d4b4 546 header[2] = 0;
nickludlam 6:79100379d4b4 547 header[3] = 0;
nickludlam 6:79100379d4b4 548
nickludlam 6:79100379d4b4 549 /* Create string header in messagePack format */
nickludlam 6:79100379d4b4 550 header[4] = _MP_FIXRAW_MIN;
nickludlam 6:79100379d4b4 551 while ((*eventName != '\0') && (headerSize < sizeof(header)))
nickludlam 6:79100379d4b4 552 {
nickludlam 6:79100379d4b4 553 /* Copy string, update messagePack byte */
nickludlam 6:79100379d4b4 554 header[4]++;
nickludlam 6:79100379d4b4 555 header[headerSize++] = *eventName++;
nickludlam 6:79100379d4b4 556 }
nickludlam 6:79100379d4b4 557
nickludlam 6:79100379d4b4 558 if (eventSize > ((uint16_t)SPI_MAX_PAYLOAD_SIZE_BYTES - headerSize))
nickludlam 6:79100379d4b4 559 {
nickludlam 6:79100379d4b4 560 _LOG("Event is too big.\r\n");
nickludlam 6:79100379d4b4 561 return false;
nickludlam 6:79100379d4b4 562 }
nickludlam 6:79100379d4b4 563
nickludlam 6:79100379d4b4 564 initTransaction(&tr);
nickludlam 6:79100379d4b4 565
nickludlam 6:79100379d4b4 566 tr.command = SPI_CMD_SEND_EVENT_PACKED;
nickludlam 6:79100379d4b4 567 tr.tx[0].buffer = (uint8_t *)header;
nickludlam 6:79100379d4b4 568 tr.tx[0].dataSize = headerSize;
nickludlam 6:79100379d4b4 569 tr.tx[1].buffer = eventBuffer;
nickludlam 6:79100379d4b4 570 tr.tx[1].dataSize = eventSize;
nickludlam 6:79100379d4b4 571
nickludlam 6:79100379d4b4 572 return transaction(&tr);
nickludlam 6:79100379d4b4 573 }
nickludlam 6:79100379d4b4 574
nickludlam 0:b4ccb530b9eb 575 #ifdef BERGCLOUD_PACK_UNPACK
nickludlam 0:b4ccb530b9eb 576 bool BERGCloudBase::sendEvent(uint8_t eventCode, BERGCloudMessageBuffer& buffer)
nickludlam 0:b4ccb530b9eb 577 {
nickludlam 0:b4ccb530b9eb 578 bool result;
nickludlam 0:b4ccb530b9eb 579
nickludlam 0:b4ccb530b9eb 580 result = _sendEvent(eventCode, buffer.ptr(), buffer.used(), SPI_CMD_SEND_EVENT_PACKED);
nickludlam 0:b4ccb530b9eb 581
nickludlam 0:b4ccb530b9eb 582 buffer.clear();
nickludlam 0:b4ccb530b9eb 583 return result;
nickludlam 0:b4ccb530b9eb 584 }
nickludlam 6:79100379d4b4 585
nickludlam 6:79100379d4b4 586 bool BERGCloudBase::sendEvent(const char *eventName, BERGCloudMessageBuffer& buffer)
nickludlam 6:79100379d4b4 587 {
nickludlam 6:79100379d4b4 588 /* Returns TRUE if the event is sent successfully */
nickludlam 6:79100379d4b4 589
nickludlam 6:79100379d4b4 590 _BC_SPI_TRANSACTION tr;
nickludlam 6:79100379d4b4 591 uint8_t headerSize = 5; /* Four bytes of SPI header, one byte of messagePack type */
nickludlam 6:79100379d4b4 592 uint8_t header[5 + _MAX_FIXRAW] = {0}; /* Header size plus maximum name string size */
nickludlam 6:79100379d4b4 593
nickludlam 6:79100379d4b4 594 if ((eventName == NULL) || (eventName[0] == '\0'))
nickludlam 6:79100379d4b4 595 {
nickludlam 6:79100379d4b4 596 _LOG("Event name must be at least one character.\r\n");
nickludlam 6:79100379d4b4 597 return false;
nickludlam 6:79100379d4b4 598 }
nickludlam 6:79100379d4b4 599
nickludlam 6:79100379d4b4 600 /* Create SPI header */
nickludlam 6:79100379d4b4 601 header[0] = BC_EVENT_NAMED_PACKED & BC_EVENT_ID_MASK;
nickludlam 6:79100379d4b4 602 header[1] = 0;
nickludlam 6:79100379d4b4 603 header[2] = 0;
nickludlam 6:79100379d4b4 604 header[3] = 0;
nickludlam 6:79100379d4b4 605
nickludlam 6:79100379d4b4 606 /* Create string header in messagePack format */
nickludlam 6:79100379d4b4 607 header[4] = _MP_FIXRAW_MIN;
nickludlam 6:79100379d4b4 608 while ((*eventName != '\0') && (headerSize < sizeof(header)))
nickludlam 6:79100379d4b4 609 {
nickludlam 6:79100379d4b4 610 /* Copy string, update messagePack byte */
nickludlam 6:79100379d4b4 611 header[4]++;
nickludlam 6:79100379d4b4 612 header[headerSize++] = *eventName++;
nickludlam 6:79100379d4b4 613 }
nickludlam 6:79100379d4b4 614
nickludlam 6:79100379d4b4 615 if (buffer.used() > ((uint16_t)SPI_MAX_PAYLOAD_SIZE_BYTES - headerSize))
nickludlam 6:79100379d4b4 616 {
nickludlam 6:79100379d4b4 617 _LOG("Event is too big.\r\n");
nickludlam 6:79100379d4b4 618 return false;
nickludlam 6:79100379d4b4 619 }
nickludlam 6:79100379d4b4 620
nickludlam 6:79100379d4b4 621 initTransaction(&tr);
nickludlam 6:79100379d4b4 622
nickludlam 6:79100379d4b4 623 tr.command = SPI_CMD_SEND_EVENT_PACKED;
nickludlam 6:79100379d4b4 624 tr.tx[0].buffer = (uint8_t *)header;
nickludlam 6:79100379d4b4 625 tr.tx[0].dataSize = headerSize;
nickludlam 6:79100379d4b4 626 tr.tx[1].buffer = buffer.ptr();
nickludlam 6:79100379d4b4 627 tr.tx[1].dataSize = buffer.used();
nickludlam 6:79100379d4b4 628
nickludlam 6:79100379d4b4 629 return transaction(&tr);
nickludlam 6:79100379d4b4 630 }
nickludlam 0:b4ccb530b9eb 631 #endif
nickludlam 0:b4ccb530b9eb 632
nickludlam 0:b4ccb530b9eb 633 bool BERGCloudBase::getConnectionState(uint8_t& state)
nickludlam 0:b4ccb530b9eb 634 {
nickludlam 0:b4ccb530b9eb 635 _BC_SPI_TRANSACTION tr;
nickludlam 0:b4ccb530b9eb 636
nickludlam 0:b4ccb530b9eb 637 initTransaction(&tr);
nickludlam 0:b4ccb530b9eb 638
nickludlam 0:b4ccb530b9eb 639 tr.command = SPI_CMD_GET_CONNECT_STATE;
nickludlam 0:b4ccb530b9eb 640 tr.rx[0].buffer = &state;
nickludlam 0:b4ccb530b9eb 641 tr.rx[0].bufferSize = sizeof(state);
nickludlam 0:b4ccb530b9eb 642
nickludlam 0:b4ccb530b9eb 643 return transaction(&tr);
nickludlam 0:b4ccb530b9eb 644 }
nickludlam 0:b4ccb530b9eb 645
nickludlam 0:b4ccb530b9eb 646 bool BERGCloudBase::getSignalQuality(int8_t& rssi, uint8_t& lqi)
nickludlam 0:b4ccb530b9eb 647 {
nickludlam 0:b4ccb530b9eb 648 _BC_SPI_TRANSACTION tr;
nickludlam 0:b4ccb530b9eb 649
nickludlam 0:b4ccb530b9eb 650 initTransaction(&tr);
nickludlam 0:b4ccb530b9eb 651
nickludlam 0:b4ccb530b9eb 652 tr.command = SPI_CMD_GET_SIGNAL_QUALITY;
nickludlam 0:b4ccb530b9eb 653 tr.rx[0].buffer = (uint8_t *)&rssi;
nickludlam 0:b4ccb530b9eb 654 tr.rx[0].bufferSize = sizeof(rssi);
nickludlam 0:b4ccb530b9eb 655 tr.rx[1].buffer = &lqi;
nickludlam 0:b4ccb530b9eb 656 tr.rx[1].bufferSize = sizeof(lqi);
nickludlam 0:b4ccb530b9eb 657
nickludlam 0:b4ccb530b9eb 658 return transaction(&tr);
nickludlam 0:b4ccb530b9eb 659 }
nickludlam 0:b4ccb530b9eb 660
nickludlam 4:5a04c00b5b6f 661 bool BERGCloudBase::connect(const uint8_t (&key)[BC_KEY_SIZE_BYTES], uint16_t version, bool waitForConnected)
nickludlam 0:b4ccb530b9eb 662 {
nickludlam 0:b4ccb530b9eb 663 _BC_SPI_TRANSACTION tr;
nickludlam 0:b4ccb530b9eb 664 uint16_t hostType = BC_HOST_UNKNOWN;
nickludlam 0:b4ccb530b9eb 665 uint8_t connectData [sizeof(version) + sizeof(hostType)];
nickludlam 0:b4ccb530b9eb 666
nickludlam 0:b4ccb530b9eb 667 uint8_t lastState = BC_CONNECT_STATE_DISCONNECTED;
nickludlam 0:b4ccb530b9eb 668 uint8_t state;
nickludlam 0:b4ccb530b9eb 669
nickludlam 0:b4ccb530b9eb 670 #ifndef BERGCLOUD_NO_HOST_TYPE
nickludlam 0:b4ccb530b9eb 671 /* Get host type */
nickludlam 0:b4ccb530b9eb 672 hostType = getHostType();
nickludlam 0:b4ccb530b9eb 673 #endif
nickludlam 0:b4ccb530b9eb 674
nickludlam 0:b4ccb530b9eb 675 initTransaction(&tr);
nickludlam 0:b4ccb530b9eb 676
nickludlam 0:b4ccb530b9eb 677 connectData[0] = hostType;
nickludlam 0:b4ccb530b9eb 678 connectData[1] = hostType >> 8;
nickludlam 0:b4ccb530b9eb 679 connectData[2] = version;
nickludlam 0:b4ccb530b9eb 680 connectData[3] = version >> 8;
nickludlam 0:b4ccb530b9eb 681
nickludlam 4:5a04c00b5b6f 682 tr.command = SPI_CMD_SEND_ANNOUNCE;
nickludlam 4:5a04c00b5b6f 683 tr.tx[0].buffer = (uint8_t *)key;
nickludlam 4:5a04c00b5b6f 684 tr.tx[0].dataSize = sizeof(key);
nickludlam 0:b4ccb530b9eb 685 tr.tx[1].buffer = connectData;
nickludlam 0:b4ccb530b9eb 686 tr.tx[1].dataSize = sizeof(connectData);
nickludlam 0:b4ccb530b9eb 687
nickludlam 0:b4ccb530b9eb 688 if (!transaction(&tr))
nickludlam 0:b4ccb530b9eb 689 {
nickludlam 0:b4ccb530b9eb 690 return false;
nickludlam 0:b4ccb530b9eb 691 }
nickludlam 0:b4ccb530b9eb 692
nickludlam 0:b4ccb530b9eb 693 if (waitForConnected)
nickludlam 0:b4ccb530b9eb 694 {
nickludlam 0:b4ccb530b9eb 695 /* Poll until connected */
nickludlam 0:b4ccb530b9eb 696 do {
nickludlam 0:b4ccb530b9eb 697 timerReset();
nickludlam 0:b4ccb530b9eb 698 while (timerRead_mS() < CONNECT_POLL_RATE_MS);
nickludlam 0:b4ccb530b9eb 699
nickludlam 0:b4ccb530b9eb 700 if (!getConnectionState(state))
nickludlam 0:b4ccb530b9eb 701 {
nickludlam 0:b4ccb530b9eb 702 return false;
nickludlam 0:b4ccb530b9eb 703 }
nickludlam 0:b4ccb530b9eb 704
nickludlam 0:b4ccb530b9eb 705 if (state != lastState)
nickludlam 0:b4ccb530b9eb 706 {
nickludlam 0:b4ccb530b9eb 707 switch (state)
nickludlam 0:b4ccb530b9eb 708 {
nickludlam 0:b4ccb530b9eb 709 case BC_CONNECT_STATE_CONNECTED:
nickludlam 0:b4ccb530b9eb 710 _LOG("connect: Connected\r\n");
nickludlam 0:b4ccb530b9eb 711 break;
nickludlam 0:b4ccb530b9eb 712 case BC_CONNECT_STATE_CONNECTING:
nickludlam 0:b4ccb530b9eb 713 _LOG("connect: Connecting...\r\n");
nickludlam 0:b4ccb530b9eb 714 break;
nickludlam 0:b4ccb530b9eb 715 default:
nickludlam 0:b4ccb530b9eb 716 case BC_CONNECT_STATE_DISCONNECTED:
nickludlam 0:b4ccb530b9eb 717 _LOG("connect: Disconnected\r\n");
nickludlam 0:b4ccb530b9eb 718 break;
nickludlam 0:b4ccb530b9eb 719 }
nickludlam 0:b4ccb530b9eb 720
nickludlam 0:b4ccb530b9eb 721 lastState = state;
nickludlam 0:b4ccb530b9eb 722 }
nickludlam 0:b4ccb530b9eb 723
nickludlam 0:b4ccb530b9eb 724 } while (state != BC_CONNECT_STATE_CONNECTED);
nickludlam 0:b4ccb530b9eb 725 }
nickludlam 0:b4ccb530b9eb 726
nickludlam 0:b4ccb530b9eb 727 return true;
nickludlam 0:b4ccb530b9eb 728 }
nickludlam 0:b4ccb530b9eb 729
nickludlam 6:79100379d4b4 730 bool BERGCloudBase::connect(const char *key, uint16_t version, bool waitForConnected)
nickludlam 6:79100379d4b4 731 {
nickludlam 6:79100379d4b4 732 unsigned int tmp_key[BC_KEY_SIZE_BYTES] = {0};
nickludlam 6:79100379d4b4 733 uint8_t _key[BC_KEY_SIZE_BYTES] = {0};
nickludlam 6:79100379d4b4 734 uint8_t i;
nickludlam 6:79100379d4b4 735
nickludlam 6:79100379d4b4 736 /* Convert key from ASCII */
nickludlam 6:79100379d4b4 737 if (key != NULL)
nickludlam 6:79100379d4b4 738 {
nickludlam 6:79100379d4b4 739 if (sscanf(key, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
nickludlam 6:79100379d4b4 740 &tmp_key[0], &tmp_key[1], &tmp_key[2], &tmp_key[3],
nickludlam 6:79100379d4b4 741 &tmp_key[4], &tmp_key[5], &tmp_key[6], &tmp_key[7],
nickludlam 6:79100379d4b4 742 &tmp_key[8], &tmp_key[9], &tmp_key[10], &tmp_key[11],
nickludlam 6:79100379d4b4 743 &tmp_key[12], &tmp_key[13], &tmp_key[14], &tmp_key[15]) == 16)
nickludlam 6:79100379d4b4 744 {
nickludlam 6:79100379d4b4 745 for (i=0; i<sizeof(_key); i++)
nickludlam 6:79100379d4b4 746 {
nickludlam 6:79100379d4b4 747 _key[i] = (uint8_t)tmp_key[i];
nickludlam 6:79100379d4b4 748 }
nickludlam 6:79100379d4b4 749 }
nickludlam 6:79100379d4b4 750 }
nickludlam 6:79100379d4b4 751
nickludlam 6:79100379d4b4 752 return connect(_key, version, waitForConnected);
nickludlam 6:79100379d4b4 753 }
nickludlam 6:79100379d4b4 754
nickludlam 0:b4ccb530b9eb 755 bool BERGCloudBase::getClaimingState(uint8_t& state)
nickludlam 0:b4ccb530b9eb 756 {
nickludlam 0:b4ccb530b9eb 757 _BC_SPI_TRANSACTION tr;
nickludlam 0:b4ccb530b9eb 758
nickludlam 0:b4ccb530b9eb 759 initTransaction(&tr);
nickludlam 0:b4ccb530b9eb 760
nickludlam 0:b4ccb530b9eb 761 tr.command = SPI_CMD_GET_CLAIM_STATE;
nickludlam 0:b4ccb530b9eb 762 tr.rx[0].buffer = &state;
nickludlam 0:b4ccb530b9eb 763 tr.rx[0].bufferSize = sizeof(state);
nickludlam 0:b4ccb530b9eb 764
nickludlam 0:b4ccb530b9eb 765 return transaction(&tr);
nickludlam 0:b4ccb530b9eb 766 }
nickludlam 0:b4ccb530b9eb 767
nickludlam 0:b4ccb530b9eb 768 bool BERGCloudBase::getClaimcode(const char (&claimcode)[BC_CLAIMCODE_SIZE_BYTES])
nickludlam 0:b4ccb530b9eb 769 {
nickludlam 0:b4ccb530b9eb 770 _BC_SPI_TRANSACTION tr;
nickludlam 0:b4ccb530b9eb 771
nickludlam 0:b4ccb530b9eb 772 initTransaction(&tr);
nickludlam 0:b4ccb530b9eb 773
nickludlam 0:b4ccb530b9eb 774 tr.command = SPI_CMD_GET_CLAIMCODE;
nickludlam 0:b4ccb530b9eb 775 tr.rx[0].buffer = (uint8_t *)claimcode;
nickludlam 0:b4ccb530b9eb 776 tr.rx[0].bufferSize = sizeof(claimcode);
nickludlam 0:b4ccb530b9eb 777
nickludlam 0:b4ccb530b9eb 778 return transaction(&tr);
nickludlam 0:b4ccb530b9eb 779 }
nickludlam 0:b4ccb530b9eb 780
nickludlam 0:b4ccb530b9eb 781 bool BERGCloudBase::getEUI64(uint8_t type, uint8_t (&eui64)[BC_EUI64_SIZE_BYTES])
nickludlam 0:b4ccb530b9eb 782 {
nickludlam 0:b4ccb530b9eb 783 _BC_SPI_TRANSACTION tr;
nickludlam 0:b4ccb530b9eb 784
nickludlam 0:b4ccb530b9eb 785 initTransaction(&tr);
nickludlam 0:b4ccb530b9eb 786
nickludlam 0:b4ccb530b9eb 787 tr.command = SPI_CMD_GET_EUI64;
nickludlam 0:b4ccb530b9eb 788 tr.tx[0].buffer = &type;
nickludlam 0:b4ccb530b9eb 789 tr.tx[0].dataSize = sizeof(uint8_t);
nickludlam 0:b4ccb530b9eb 790 tr.rx[0].buffer = eui64;
nickludlam 0:b4ccb530b9eb 791 tr.rx[0].bufferSize = sizeof(eui64);
nickludlam 0:b4ccb530b9eb 792
nickludlam 0:b4ccb530b9eb 793 return transaction(&tr);
nickludlam 0:b4ccb530b9eb 794 }
nickludlam 0:b4ccb530b9eb 795
nickludlam 0:b4ccb530b9eb 796 bool BERGCloudBase::getDeviceAddress(uint8_t (&address)[BC_ADDRESS_SIZE_BYTES])
nickludlam 0:b4ccb530b9eb 797 {
nickludlam 0:b4ccb530b9eb 798 _BC_SPI_TRANSACTION tr;
nickludlam 0:b4ccb530b9eb 799
nickludlam 0:b4ccb530b9eb 800 initTransaction(&tr);
nickludlam 0:b4ccb530b9eb 801
nickludlam 0:b4ccb530b9eb 802 tr.command = SPI_CMD_GET_ADDRESS;
nickludlam 0:b4ccb530b9eb 803 tr.rx[0].buffer = address;
nickludlam 0:b4ccb530b9eb 804 tr.rx[0].bufferSize = sizeof(address);
nickludlam 0:b4ccb530b9eb 805
nickludlam 0:b4ccb530b9eb 806 return transaction(&tr);
nickludlam 0:b4ccb530b9eb 807 }
nickludlam 0:b4ccb530b9eb 808
nickludlam 0:b4ccb530b9eb 809 bool BERGCloudBase::setDisplayStyle(uint8_t style)
nickludlam 0:b4ccb530b9eb 810 {
nickludlam 0:b4ccb530b9eb 811 _BC_SPI_TRANSACTION tr;
nickludlam 0:b4ccb530b9eb 812
nickludlam 0:b4ccb530b9eb 813 initTransaction(&tr);
nickludlam 0:b4ccb530b9eb 814
nickludlam 0:b4ccb530b9eb 815 tr.command = SPI_CMD_SET_DISPLAY_STYLE;
nickludlam 0:b4ccb530b9eb 816 tr.tx[0].buffer = &style;
nickludlam 0:b4ccb530b9eb 817 tr.tx[0].dataSize = sizeof(style);
nickludlam 0:b4ccb530b9eb 818
nickludlam 0:b4ccb530b9eb 819 return transaction(&tr);
nickludlam 0:b4ccb530b9eb 820 }
nickludlam 0:b4ccb530b9eb 821
nickludlam 0:b4ccb530b9eb 822 bool BERGCloudBase::clearDisplay(void)
nickludlam 0:b4ccb530b9eb 823 {
nickludlam 0:b4ccb530b9eb 824 return setDisplayStyle(BC_DISPLAY_CLEAR);
nickludlam 0:b4ccb530b9eb 825 }
nickludlam 0:b4ccb530b9eb 826
nickludlam 0:b4ccb530b9eb 827 bool BERGCloudBase::display(const char *text)
nickludlam 0:b4ccb530b9eb 828 {
nickludlam 0:b4ccb530b9eb 829 _BC_SPI_TRANSACTION tr;
nickludlam 0:b4ccb530b9eb 830 uint8_t strLen = 0;
nickludlam 0:b4ccb530b9eb 831 const char *tmp = text;
nickludlam 0:b4ccb530b9eb 832
nickludlam 0:b4ccb530b9eb 833 if (text == NULL)
nickludlam 0:b4ccb530b9eb 834 {
nickludlam 0:b4ccb530b9eb 835 return false;
nickludlam 0:b4ccb530b9eb 836 }
nickludlam 0:b4ccb530b9eb 837
nickludlam 0:b4ccb530b9eb 838 initTransaction(&tr);
nickludlam 0:b4ccb530b9eb 839
nickludlam 0:b4ccb530b9eb 840 /* Get string length excluding terminator */
nickludlam 0:b4ccb530b9eb 841 while ((*tmp++ != '\0') && (strLen < UINT8_MAX))
nickludlam 0:b4ccb530b9eb 842 {
nickludlam 0:b4ccb530b9eb 843 strLen++;
nickludlam 0:b4ccb530b9eb 844 }
nickludlam 0:b4ccb530b9eb 845
nickludlam 0:b4ccb530b9eb 846 tr.command = SPI_CMD_DISPLAY_PRINT;
nickludlam 0:b4ccb530b9eb 847 tr.tx[0].buffer = (uint8_t *)text;
nickludlam 0:b4ccb530b9eb 848 tr.tx[0].dataSize = strLen;
nickludlam 0:b4ccb530b9eb 849
nickludlam 0:b4ccb530b9eb 850 return transaction(&tr);
nickludlam 0:b4ccb530b9eb 851 }
nickludlam 0:b4ccb530b9eb 852
nickludlam 0:b4ccb530b9eb 853 uint16_t BERGCloudBase::Crc16(uint8_t data, uint16_t crc)
nickludlam 0:b4ccb530b9eb 854 {
nickludlam 5:2e04a8b3fc25 855 /* CRC16 CCITT (0x1021) */
nickludlam 0:b4ccb530b9eb 856
nickludlam 5:2e04a8b3fc25 857 uint8_t s;
nickludlam 5:2e04a8b3fc25 858 uint16_t t;
nickludlam 0:b4ccb530b9eb 859
nickludlam 5:2e04a8b3fc25 860 s = data ^ (crc >> 8);
nickludlam 5:2e04a8b3fc25 861 t = s ^ (s >> 4);
nickludlam 5:2e04a8b3fc25 862 return (crc << 8) ^ t ^ (t << 5) ^ (t << 12);
nickludlam 0:b4ccb530b9eb 863 }
nickludlam 0:b4ccb530b9eb 864
nickludlam 0:b4ccb530b9eb 865 uint8_t BERGCloudBase::SPITransaction(uint8_t dataOut, bool finalCS)
nickludlam 0:b4ccb530b9eb 866 {
nickludlam 0:b4ccb530b9eb 867 uint8_t dataIn = 0;
nickludlam 0:b4ccb530b9eb 868
nickludlam 0:b4ccb530b9eb 869 SPITransaction(&dataOut, &dataIn, (uint16_t)1, finalCS);
nickludlam 0:b4ccb530b9eb 870
nickludlam 0:b4ccb530b9eb 871 return dataIn;
nickludlam 0:b4ccb530b9eb 872 }
nickludlam 0:b4ccb530b9eb 873
nickludlam 5:2e04a8b3fc25 874 void BERGCloudBase::lockTake(void)
nickludlam 5:2e04a8b3fc25 875 {
nickludlam 5:2e04a8b3fc25 876 }
nickludlam 5:2e04a8b3fc25 877
nickludlam 5:2e04a8b3fc25 878 void BERGCloudBase::lockRelease(void)
nickludlam 5:2e04a8b3fc25 879 {
nickludlam 5:2e04a8b3fc25 880 }
nickludlam 5:2e04a8b3fc25 881
nickludlam 0:b4ccb530b9eb 882 void BERGCloudBase::begin(void)
nickludlam 0:b4ccb530b9eb 883 {
nickludlam 0:b4ccb530b9eb 884 synced = false;
nickludlam 0:b4ccb530b9eb 885 lastResponse = SPI_RSP_SUCCESS;
nickludlam 6:79100379d4b4 886
nickludlam 6:79100379d4b4 887 /* Print library version */
nickludlam 6:79100379d4b4 888 _LOG("\r\nBERGCloud library version ");
nickludlam 6:79100379d4b4 889 _LOG_HEX(BERGCLOUD_LIB_VERSION >> 8);
nickludlam 6:79100379d4b4 890 _LOG(".");
nickludlam 6:79100379d4b4 891 _LOG_HEX(BERGCLOUD_LIB_VERSION & 0xff);
nickludlam 6:79100379d4b4 892 _LOG("\r\n");
nickludlam 0:b4ccb530b9eb 893 }
nickludlam 0:b4ccb530b9eb 894
nickludlam 0:b4ccb530b9eb 895 void BERGCloudBase::end(void)
nickludlam 0:b4ccb530b9eb 896 {
nickludlam 0:b4ccb530b9eb 897 }
nickludlam 6:79100379d4b4 898
nickludlam 6:79100379d4b4 899 void BERGCloudBase::bytecpy(uint8_t *dst, uint8_t *src, uint16_t size)
nickludlam 6:79100379d4b4 900 {
nickludlam 6:79100379d4b4 901 /* memcpy() cannot be used when buffers overlap */
nickludlam 6:79100379d4b4 902 while (size-- > 0)
nickludlam 6:79100379d4b4 903 {
nickludlam 6:79100379d4b4 904 *dst++ = *src++;
nickludlam 6:79100379d4b4 905 }
nickludlam 6:79100379d4b4 906 }
nickludlam 0:b4ccb530b9eb 907