Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
afLib/afLib.cpp@0:f0de320e23ac, 2017-12-01 (annotated)
- Committer:
- Rhyme
- Date:
- Fri Dec 01 06:16:31 2017 +0000
- Revision:
- 0:f0de320e23ac
OLED display for GAS pressure started working
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| Rhyme | 0:f0de320e23ac | 1 | /** |
| Rhyme | 0:f0de320e23ac | 2 | * Copyright 2015 Afero, Inc. |
| Rhyme | 0:f0de320e23ac | 3 | * |
| Rhyme | 0:f0de320e23ac | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| Rhyme | 0:f0de320e23ac | 5 | * you may not use this file except in compliance with the License. |
| Rhyme | 0:f0de320e23ac | 6 | * You may obtain a copy of the License at |
| Rhyme | 0:f0de320e23ac | 7 | * |
| Rhyme | 0:f0de320e23ac | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| Rhyme | 0:f0de320e23ac | 9 | * |
| Rhyme | 0:f0de320e23ac | 10 | * Unless required by applicable law or agreed to in writing, software |
| Rhyme | 0:f0de320e23ac | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| Rhyme | 0:f0de320e23ac | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| Rhyme | 0:f0de320e23ac | 13 | * See the License for the specific language governing permissions and |
| Rhyme | 0:f0de320e23ac | 14 | * limitations under the License. |
| Rhyme | 0:f0de320e23ac | 15 | */ |
| Rhyme | 0:f0de320e23ac | 16 | |
| Rhyme | 0:f0de320e23ac | 17 | #include "mbed.h" |
| Rhyme | 0:f0de320e23ac | 18 | #include "afLib.h" |
| Rhyme | 0:f0de320e23ac | 19 | #include "afErrors.h" |
| Rhyme | 0:f0de320e23ac | 20 | #include "msg_types.h" |
| Rhyme | 0:f0de320e23ac | 21 | |
| Rhyme | 0:f0de320e23ac | 22 | #define IS_MCU_ATTR(x) (x >= 0 && x < 1024) |
| Rhyme | 0:f0de320e23ac | 23 | |
| Rhyme | 0:f0de320e23ac | 24 | static iafLib *_iaflib = NULL; |
| Rhyme | 0:f0de320e23ac | 25 | |
| Rhyme | 0:f0de320e23ac | 26 | #define MAX_SYNC_RETRIES 10 |
| Rhyme | 0:f0de320e23ac | 27 | static long lastSync = 0; |
| Rhyme | 0:f0de320e23ac | 28 | static int syncRetries = 0; |
| Rhyme | 0:f0de320e23ac | 29 | |
| Rhyme | 0:f0de320e23ac | 30 | /** |
| Rhyme | 0:f0de320e23ac | 31 | * create |
| Rhyme | 0:f0de320e23ac | 32 | * |
| Rhyme | 0:f0de320e23ac | 33 | * The public constructor for the afLib. This allows us to create the afLib object once and hold a reference to it. |
| Rhyme | 0:f0de320e23ac | 34 | */ |
| Rhyme | 0:f0de320e23ac | 35 | iafLib *iafLib::create(PinName mcuInterrupt, isr isrWrapper, |
| Rhyme | 0:f0de320e23ac | 36 | onAttributeSet attrSet, onAttributeSetComplete attrSetComplete, afSPI *theSPI) |
| Rhyme | 0:f0de320e23ac | 37 | { |
| Rhyme | 0:f0de320e23ac | 38 | if (_iaflib == NULL) { |
| Rhyme | 0:f0de320e23ac | 39 | _iaflib = new afLib( mcuInterrupt, isrWrapper, attrSet, attrSetComplete, theSPI); |
| Rhyme | 0:f0de320e23ac | 40 | } |
| Rhyme | 0:f0de320e23ac | 41 | |
| Rhyme | 0:f0de320e23ac | 42 | return _iaflib; |
| Rhyme | 0:f0de320e23ac | 43 | } |
| Rhyme | 0:f0de320e23ac | 44 | |
| Rhyme | 0:f0de320e23ac | 45 | void iafLib::destroy() |
| Rhyme | 0:f0de320e23ac | 46 | { |
| Rhyme | 0:f0de320e23ac | 47 | afLib *p = (afLib*)_iaflib; |
| Rhyme | 0:f0de320e23ac | 48 | delete p; |
| Rhyme | 0:f0de320e23ac | 49 | _iaflib = NULL; |
| Rhyme | 0:f0de320e23ac | 50 | } |
| Rhyme | 0:f0de320e23ac | 51 | |
| Rhyme | 0:f0de320e23ac | 52 | /** |
| Rhyme | 0:f0de320e23ac | 53 | * getRequestId |
| Rhyme | 0:f0de320e23ac | 54 | * by Motoo Tanaka on 16-Nov-2017 |
| Rhyme | 0:f0de320e23ac | 55 | */ |
| Rhyme | 0:f0de320e23ac | 56 | int afLib::getRequestId(void) |
| Rhyme | 0:f0de320e23ac | 57 | { |
| Rhyme | 0:f0de320e23ac | 58 | return( _requestId ) ; |
| Rhyme | 0:f0de320e23ac | 59 | } |
| Rhyme | 0:f0de320e23ac | 60 | |
| Rhyme | 0:f0de320e23ac | 61 | /** |
| Rhyme | 0:f0de320e23ac | 62 | * afLib |
| Rhyme | 0:f0de320e23ac | 63 | * |
| Rhyme | 0:f0de320e23ac | 64 | * The private constructor for the afLib. This one actually initializes the afLib and prepares it for use. |
| Rhyme | 0:f0de320e23ac | 65 | */ |
| Rhyme | 0:f0de320e23ac | 66 | afLib::afLib(PinName mcuInterrupt, isr isrWrapper, |
| Rhyme | 0:f0de320e23ac | 67 | onAttributeSet attrSet, onAttributeSetComplete attrSetComplete, afSPI *theSPI) : fco(mcuInterrupt) |
| Rhyme | 0:f0de320e23ac | 68 | { |
| Rhyme | 0:f0de320e23ac | 69 | checkLastSync = new Timer(); |
| Rhyme | 0:f0de320e23ac | 70 | checkLastSync->start(); |
| Rhyme | 0:f0de320e23ac | 71 | queueInit(); |
| Rhyme | 0:f0de320e23ac | 72 | _theSPI= theSPI; |
| Rhyme | 0:f0de320e23ac | 73 | _request.p_value = NULL; |
| Rhyme | 0:f0de320e23ac | 74 | |
| Rhyme | 0:f0de320e23ac | 75 | //_spiSettings = SPISettings(1000000, LSBFIRST, SPI_MODE0); |
| Rhyme | 0:f0de320e23ac | 76 | _interrupts_pending = 0; |
| Rhyme | 0:f0de320e23ac | 77 | _state = STATE_IDLE; |
| Rhyme | 0:f0de320e23ac | 78 | |
| Rhyme | 0:f0de320e23ac | 79 | _writeCmd = NULL; |
| Rhyme | 0:f0de320e23ac | 80 | _writeCmdOffset = 0; |
| Rhyme | 0:f0de320e23ac | 81 | |
| Rhyme | 0:f0de320e23ac | 82 | _outstandingSetGetAttrId = 0; |
| Rhyme | 0:f0de320e23ac | 83 | |
| Rhyme | 0:f0de320e23ac | 84 | _readCmd = NULL; |
| Rhyme | 0:f0de320e23ac | 85 | _readCmdOffset = 0; |
| Rhyme | 0:f0de320e23ac | 86 | _readBufferLen = 0; |
| Rhyme | 0:f0de320e23ac | 87 | |
| Rhyme | 0:f0de320e23ac | 88 | _txStatus = new StatusCommand(); |
| Rhyme | 0:f0de320e23ac | 89 | _rxStatus = new StatusCommand(); |
| Rhyme | 0:f0de320e23ac | 90 | |
| Rhyme | 0:f0de320e23ac | 91 | _onAttrSet = attrSet; |
| Rhyme | 0:f0de320e23ac | 92 | _onAttrSetComplete = attrSetComplete; |
| Rhyme | 0:f0de320e23ac | 93 | _theSPI->begin(); |
| Rhyme | 0:f0de320e23ac | 94 | |
| Rhyme | 0:f0de320e23ac | 95 | // AJS where does this get moved to?? |
| Rhyme | 0:f0de320e23ac | 96 | #ifdef ARDUINO |
| Rhyme | 0:f0de320e23ac | 97 | pinMode(mcuInterrupt, INPUT); |
| Rhyme | 0:f0de320e23ac | 98 | attachInterrupt(mcuInterrupt, isrWrapper, FALLING); |
| Rhyme | 0:f0de320e23ac | 99 | #endif |
| Rhyme | 0:f0de320e23ac | 100 | fco.fall(isrWrapper); |
| Rhyme | 0:f0de320e23ac | 101 | SERIAL_PRINT_DBG_ASR("afLib init done!!\n"); |
| Rhyme | 0:f0de320e23ac | 102 | } |
| Rhyme | 0:f0de320e23ac | 103 | //wsugi 20161128 |
| Rhyme | 0:f0de320e23ac | 104 | afLib::~afLib() |
| Rhyme | 0:f0de320e23ac | 105 | { |
| Rhyme | 0:f0de320e23ac | 106 | SERIAL_PRINT_DBG_ASR("deleted\n"); |
| Rhyme | 0:f0de320e23ac | 107 | if(_readBuffer != NULL) |
| Rhyme | 0:f0de320e23ac | 108 | { |
| Rhyme | 0:f0de320e23ac | 109 | delete[] (_readBuffer); |
| Rhyme | 0:f0de320e23ac | 110 | _readBuffer = NULL; |
| Rhyme | 0:f0de320e23ac | 111 | } |
| Rhyme | 0:f0de320e23ac | 112 | |
| Rhyme | 0:f0de320e23ac | 113 | if(_writeBuffer != NULL) |
| Rhyme | 0:f0de320e23ac | 114 | { |
| Rhyme | 0:f0de320e23ac | 115 | delete[] (_writeBuffer); |
| Rhyme | 0:f0de320e23ac | 116 | _writeBuffer = NULL; |
| Rhyme | 0:f0de320e23ac | 117 | } |
| Rhyme | 0:f0de320e23ac | 118 | |
| Rhyme | 0:f0de320e23ac | 119 | if(_readCmd != NULL) |
| Rhyme | 0:f0de320e23ac | 120 | { |
| Rhyme | 0:f0de320e23ac | 121 | delete (_readCmd); |
| Rhyme | 0:f0de320e23ac | 122 | _readCmd = NULL; |
| Rhyme | 0:f0de320e23ac | 123 | } |
| Rhyme | 0:f0de320e23ac | 124 | |
| Rhyme | 0:f0de320e23ac | 125 | if(_writeCmd != NULL) |
| Rhyme | 0:f0de320e23ac | 126 | { |
| Rhyme | 0:f0de320e23ac | 127 | delete (_writeCmd); |
| Rhyme | 0:f0de320e23ac | 128 | _writeCmd = NULL; |
| Rhyme | 0:f0de320e23ac | 129 | } |
| Rhyme | 0:f0de320e23ac | 130 | |
| Rhyme | 0:f0de320e23ac | 131 | if(_txStatus != NULL) |
| Rhyme | 0:f0de320e23ac | 132 | { |
| Rhyme | 0:f0de320e23ac | 133 | delete (_txStatus); |
| Rhyme | 0:f0de320e23ac | 134 | _txStatus = NULL; |
| Rhyme | 0:f0de320e23ac | 135 | } |
| Rhyme | 0:f0de320e23ac | 136 | |
| Rhyme | 0:f0de320e23ac | 137 | if(_rxStatus != NULL) |
| Rhyme | 0:f0de320e23ac | 138 | { |
| Rhyme | 0:f0de320e23ac | 139 | delete (_rxStatus); |
| Rhyme | 0:f0de320e23ac | 140 | _rxStatus = NULL; |
| Rhyme | 0:f0de320e23ac | 141 | } |
| Rhyme | 0:f0de320e23ac | 142 | |
| Rhyme | 0:f0de320e23ac | 143 | for (int i = 0; i < REQUEST_QUEUE_SIZE; i++) |
| Rhyme | 0:f0de320e23ac | 144 | { |
| Rhyme | 0:f0de320e23ac | 145 | if (_requestQueue[i].p_value != NULL) |
| Rhyme | 0:f0de320e23ac | 146 | { |
| Rhyme | 0:f0de320e23ac | 147 | delete[] (_requestQueue[i].p_value); |
| Rhyme | 0:f0de320e23ac | 148 | _requestQueue[i].p_value = NULL; |
| Rhyme | 0:f0de320e23ac | 149 | } |
| Rhyme | 0:f0de320e23ac | 150 | } |
| Rhyme | 0:f0de320e23ac | 151 | |
| Rhyme | 0:f0de320e23ac | 152 | if(checkLastSync != NULL) |
| Rhyme | 0:f0de320e23ac | 153 | { |
| Rhyme | 0:f0de320e23ac | 154 | delete (checkLastSync); |
| Rhyme | 0:f0de320e23ac | 155 | checkLastSync = NULL; |
| Rhyme | 0:f0de320e23ac | 156 | } |
| Rhyme | 0:f0de320e23ac | 157 | |
| Rhyme | 0:f0de320e23ac | 158 | _iaflib = NULL; |
| Rhyme | 0:f0de320e23ac | 159 | } |
| Rhyme | 0:f0de320e23ac | 160 | //wsugi 20161128 |
| Rhyme | 0:f0de320e23ac | 161 | /** |
| Rhyme | 0:f0de320e23ac | 162 | * loop |
| Rhyme | 0:f0de320e23ac | 163 | * |
| Rhyme | 0:f0de320e23ac | 164 | * This is how the afLib gets time to run its state machine. This method should be called periodically from the |
| Rhyme | 0:f0de320e23ac | 165 | * loop() function of the Arduino sketch. |
| Rhyme | 0:f0de320e23ac | 166 | * This function pulls pending attribute operations from the queue. It takes approximately 4 calls to loop() to |
| Rhyme | 0:f0de320e23ac | 167 | * complete one attribute operation. |
| Rhyme | 0:f0de320e23ac | 168 | */ |
| Rhyme | 0:f0de320e23ac | 169 | void afLib::loop(void) { |
| Rhyme | 0:f0de320e23ac | 170 | /* |
| Rhyme | 0:f0de320e23ac | 171 | if (isIdle()) |
| Rhyme | 0:f0de320e23ac | 172 | { |
| Rhyme | 0:f0de320e23ac | 173 | // deathWish.attach(callback(WatchDogWrapper::getSelf(), &WatchDogWrapper::kick_the_bucket),10); |
| Rhyme | 0:f0de320e23ac | 174 | // deathWish.attach(&afLib::kick_the_bucket,10); |
| Rhyme | 0:f0de320e23ac | 175 | } |
| Rhyme | 0:f0de320e23ac | 176 | */ |
| Rhyme | 0:f0de320e23ac | 177 | if (isIdle() && (queueGet(&_request.messageType, &_request.requestId, &_request.attrId, &_request.valueLen, |
| Rhyme | 0:f0de320e23ac | 178 | &_request.p_value) == afSUCCESS)) { |
| Rhyme | 0:f0de320e23ac | 179 | switch (_request.messageType) { |
| Rhyme | 0:f0de320e23ac | 180 | case MSG_TYPE_GET: |
| Rhyme | 0:f0de320e23ac | 181 | doGetAttribute(_request.requestId, _request.attrId); |
| Rhyme | 0:f0de320e23ac | 182 | break; |
| Rhyme | 0:f0de320e23ac | 183 | |
| Rhyme | 0:f0de320e23ac | 184 | case MSG_TYPE_SET: |
| Rhyme | 0:f0de320e23ac | 185 | doSetAttribute(_request.requestId, _request.attrId, _request.valueLen, _request.p_value); |
| Rhyme | 0:f0de320e23ac | 186 | break; |
| Rhyme | 0:f0de320e23ac | 187 | |
| Rhyme | 0:f0de320e23ac | 188 | case MSG_TYPE_UPDATE: |
| Rhyme | 0:f0de320e23ac | 189 | doUpdateAttribute(_request.requestId, _request.attrId, 0, _request.valueLen, _request.p_value); |
| Rhyme | 0:f0de320e23ac | 190 | break; |
| Rhyme | 0:f0de320e23ac | 191 | |
| Rhyme | 0:f0de320e23ac | 192 | default: |
| Rhyme | 0:f0de320e23ac | 193 | SERIAL_PRINT_DBG_ASR("%s\n","loop: request type!"); |
| Rhyme | 0:f0de320e23ac | 194 | } |
| Rhyme | 0:f0de320e23ac | 195 | } |
| Rhyme | 0:f0de320e23ac | 196 | |
| Rhyme | 0:f0de320e23ac | 197 | if (_request.p_value != NULL) { |
| Rhyme | 0:f0de320e23ac | 198 | delete[] (_request.p_value); //wsugi delete (_request.p_value); |
| Rhyme | 0:f0de320e23ac | 199 | _request.p_value = NULL; |
| Rhyme | 0:f0de320e23ac | 200 | } |
| Rhyme | 0:f0de320e23ac | 201 | runStateMachine(); |
| Rhyme | 0:f0de320e23ac | 202 | } |
| Rhyme | 0:f0de320e23ac | 203 | |
| Rhyme | 0:f0de320e23ac | 204 | /** |
| Rhyme | 0:f0de320e23ac | 205 | * updateIntsPending |
| Rhyme | 0:f0de320e23ac | 206 | * |
| Rhyme | 0:f0de320e23ac | 207 | * Interrupt-safe method for updating the interrupt count. This is called to increment and decrement the interrupt count |
| Rhyme | 0:f0de320e23ac | 208 | * as interrupts are received and handled. |
| Rhyme | 0:f0de320e23ac | 209 | */ |
| Rhyme | 0:f0de320e23ac | 210 | void afLib::updateIntsPending(int amount) { |
| Rhyme | 0:f0de320e23ac | 211 | fco.disable_irq(); |
| Rhyme | 0:f0de320e23ac | 212 | _interrupts_pending += amount; |
| Rhyme | 0:f0de320e23ac | 213 | fco.enable_irq(); |
| Rhyme | 0:f0de320e23ac | 214 | } |
| Rhyme | 0:f0de320e23ac | 215 | |
| Rhyme | 0:f0de320e23ac | 216 | /** |
| Rhyme | 0:f0de320e23ac | 217 | * sendCommand |
| Rhyme | 0:f0de320e23ac | 218 | * |
| Rhyme | 0:f0de320e23ac | 219 | * This increments the interrupt count to kick off the state machine in the next call to loop(). |
| Rhyme | 0:f0de320e23ac | 220 | */ |
| Rhyme | 0:f0de320e23ac | 221 | void afLib::sendCommand(void) { |
| Rhyme | 0:f0de320e23ac | 222 | fco.disable_irq(); |
| Rhyme | 0:f0de320e23ac | 223 | if (_interrupts_pending == 0 && _state == STATE_IDLE) { |
| Rhyme | 0:f0de320e23ac | 224 | updateIntsPending(1); |
| Rhyme | 0:f0de320e23ac | 225 | } |
| Rhyme | 0:f0de320e23ac | 226 | fco.enable_irq(); |
| Rhyme | 0:f0de320e23ac | 227 | } |
| Rhyme | 0:f0de320e23ac | 228 | |
| Rhyme | 0:f0de320e23ac | 229 | /** |
| Rhyme | 0:f0de320e23ac | 230 | * getAttribute |
| Rhyme | 0:f0de320e23ac | 231 | * |
| Rhyme | 0:f0de320e23ac | 232 | * The public getAttribute method. This method queues the operation and returns immediately. Applications must call |
| Rhyme | 0:f0de320e23ac | 233 | * loop() for the operation to complete. |
| Rhyme | 0:f0de320e23ac | 234 | */ |
| Rhyme | 0:f0de320e23ac | 235 | int afLib::getAttribute(const uint16_t attrId) { |
| Rhyme | 0:f0de320e23ac | 236 | _requestId++; |
| Rhyme | 0:f0de320e23ac | 237 | uint8_t dummy; // This value isn't actually used. |
| Rhyme | 0:f0de320e23ac | 238 | // return queuePut(MSG_TYPE_GET, _requestId++, attrId, 0, &dummy); |
| Rhyme | 0:f0de320e23ac | 239 | return queuePut(MSG_TYPE_GET, _requestId, attrId, 0, &dummy); /* by moto on 17-Nov-2017 */ |
| Rhyme | 0:f0de320e23ac | 240 | } |
| Rhyme | 0:f0de320e23ac | 241 | |
| Rhyme | 0:f0de320e23ac | 242 | /** |
| Rhyme | 0:f0de320e23ac | 243 | * The many moods of setAttribute |
| Rhyme | 0:f0de320e23ac | 244 | * |
| Rhyme | 0:f0de320e23ac | 245 | * These are the public versions of the setAttribute method. |
| Rhyme | 0:f0de320e23ac | 246 | * These methods queue the operation and return immediately. Applications must call loop() for the operation to complete. |
| Rhyme | 0:f0de320e23ac | 247 | */ |
| Rhyme | 0:f0de320e23ac | 248 | int afLib::setAttributeBool(const uint16_t attrId, const bool value) { |
| Rhyme | 0:f0de320e23ac | 249 | _requestId++; |
| Rhyme | 0:f0de320e23ac | 250 | uint8_t val = value ? 1 : 0; |
| Rhyme | 0:f0de320e23ac | 251 | return queuePut(IS_MCU_ATTR(attrId) ? MSG_TYPE_UPDATE : MSG_TYPE_SET, _requestId, attrId, sizeof(val), |
| Rhyme | 0:f0de320e23ac | 252 | (uint8_t *)&val); |
| Rhyme | 0:f0de320e23ac | 253 | } |
| Rhyme | 0:f0de320e23ac | 254 | |
| Rhyme | 0:f0de320e23ac | 255 | int afLib::setAttribute8(const uint16_t attrId, const int8_t value) { |
| Rhyme | 0:f0de320e23ac | 256 | _requestId++; |
| Rhyme | 0:f0de320e23ac | 257 | return queuePut(IS_MCU_ATTR(attrId) ? MSG_TYPE_UPDATE : MSG_TYPE_SET, _requestId, attrId, sizeof(value), |
| Rhyme | 0:f0de320e23ac | 258 | (uint8_t *)&value); |
| Rhyme | 0:f0de320e23ac | 259 | } |
| Rhyme | 0:f0de320e23ac | 260 | |
| Rhyme | 0:f0de320e23ac | 261 | int afLib::setAttribute16(const uint16_t attrId, const int16_t value) { |
| Rhyme | 0:f0de320e23ac | 262 | _requestId++; |
| Rhyme | 0:f0de320e23ac | 263 | return queuePut(IS_MCU_ATTR(attrId) ? MSG_TYPE_UPDATE : MSG_TYPE_SET, _requestId, attrId, sizeof(value), |
| Rhyme | 0:f0de320e23ac | 264 | (uint8_t *) &value); |
| Rhyme | 0:f0de320e23ac | 265 | } |
| Rhyme | 0:f0de320e23ac | 266 | |
| Rhyme | 0:f0de320e23ac | 267 | int afLib::setAttribute32(const uint16_t attrId, const int32_t value) { |
| Rhyme | 0:f0de320e23ac | 268 | _requestId++; |
| Rhyme | 0:f0de320e23ac | 269 | return queuePut(IS_MCU_ATTR(attrId) ? MSG_TYPE_UPDATE : MSG_TYPE_SET, _requestId, attrId, sizeof(value), |
| Rhyme | 0:f0de320e23ac | 270 | (uint8_t *) &value); |
| Rhyme | 0:f0de320e23ac | 271 | } |
| Rhyme | 0:f0de320e23ac | 272 | |
| Rhyme | 0:f0de320e23ac | 273 | int afLib::setAttribute64(const uint16_t attrId, const int64_t value) { |
| Rhyme | 0:f0de320e23ac | 274 | _requestId++; |
| Rhyme | 0:f0de320e23ac | 275 | return queuePut(IS_MCU_ATTR(attrId) ? MSG_TYPE_UPDATE : MSG_TYPE_SET, _requestId, attrId, sizeof(value), |
| Rhyme | 0:f0de320e23ac | 276 | (uint8_t *) &value); |
| Rhyme | 0:f0de320e23ac | 277 | } |
| Rhyme | 0:f0de320e23ac | 278 | |
| Rhyme | 0:f0de320e23ac | 279 | int afLib::setAttribute(const uint16_t attrId, const string &value) { |
| Rhyme | 0:f0de320e23ac | 280 | _requestId++; |
| Rhyme | 0:f0de320e23ac | 281 | return queuePut(IS_MCU_ATTR(attrId) ? MSG_TYPE_UPDATE : MSG_TYPE_SET, _requestId, attrId, value.length(), |
| Rhyme | 0:f0de320e23ac | 282 | (uint8_t *) value.c_str()); |
| Rhyme | 0:f0de320e23ac | 283 | } |
| Rhyme | 0:f0de320e23ac | 284 | |
| Rhyme | 0:f0de320e23ac | 285 | int afLib::setAttribute(const uint16_t attrId, const uint16_t valueLen, const char *value) { |
| Rhyme | 0:f0de320e23ac | 286 | if (valueLen > MAX_ATTRIBUTE_SIZE) { |
| Rhyme | 0:f0de320e23ac | 287 | return afERROR_INVALID_PARAM; |
| Rhyme | 0:f0de320e23ac | 288 | } |
| Rhyme | 0:f0de320e23ac | 289 | |
| Rhyme | 0:f0de320e23ac | 290 | if (value == NULL) { |
| Rhyme | 0:f0de320e23ac | 291 | return afERROR_INVALID_PARAM; |
| Rhyme | 0:f0de320e23ac | 292 | } |
| Rhyme | 0:f0de320e23ac | 293 | |
| Rhyme | 0:f0de320e23ac | 294 | _requestId++; |
| Rhyme | 0:f0de320e23ac | 295 | return queuePut(IS_MCU_ATTR(attrId) ? MSG_TYPE_UPDATE : MSG_TYPE_SET, _requestId, attrId, valueLen, |
| Rhyme | 0:f0de320e23ac | 296 | (const uint8_t *) value); |
| Rhyme | 0:f0de320e23ac | 297 | } |
| Rhyme | 0:f0de320e23ac | 298 | |
| Rhyme | 0:f0de320e23ac | 299 | int afLib::setAttribute(const uint16_t attrId, const uint16_t valueLen, const uint8_t *value) { |
| Rhyme | 0:f0de320e23ac | 300 | if (valueLen > MAX_ATTRIBUTE_SIZE) { |
| Rhyme | 0:f0de320e23ac | 301 | return afERROR_INVALID_PARAM; |
| Rhyme | 0:f0de320e23ac | 302 | } |
| Rhyme | 0:f0de320e23ac | 303 | |
| Rhyme | 0:f0de320e23ac | 304 | if (value == NULL) { |
| Rhyme | 0:f0de320e23ac | 305 | return afERROR_INVALID_PARAM; |
| Rhyme | 0:f0de320e23ac | 306 | } |
| Rhyme | 0:f0de320e23ac | 307 | |
| Rhyme | 0:f0de320e23ac | 308 | _requestId++; |
| Rhyme | 0:f0de320e23ac | 309 | return queuePut(IS_MCU_ATTR(attrId) ? MSG_TYPE_UPDATE : MSG_TYPE_SET, _requestId, attrId, valueLen, value); |
| Rhyme | 0:f0de320e23ac | 310 | } |
| Rhyme | 0:f0de320e23ac | 311 | |
| Rhyme | 0:f0de320e23ac | 312 | int afLib::setAttributeComplete(uint8_t requestId, const uint16_t attrId, const uint16_t valueLen, const uint8_t *value) { |
| Rhyme | 0:f0de320e23ac | 313 | if (valueLen > MAX_ATTRIBUTE_SIZE) { |
| Rhyme | 0:f0de320e23ac | 314 | return afERROR_INVALID_PARAM; |
| Rhyme | 0:f0de320e23ac | 315 | } |
| Rhyme | 0:f0de320e23ac | 316 | |
| Rhyme | 0:f0de320e23ac | 317 | if (value == NULL) { |
| Rhyme | 0:f0de320e23ac | 318 | return afERROR_INVALID_PARAM; |
| Rhyme | 0:f0de320e23ac | 319 | } |
| Rhyme | 0:f0de320e23ac | 320 | |
| Rhyme | 0:f0de320e23ac | 321 | return queuePut(MSG_TYPE_UPDATE, requestId, attrId, valueLen, value); |
| Rhyme | 0:f0de320e23ac | 322 | } |
| Rhyme | 0:f0de320e23ac | 323 | |
| Rhyme | 0:f0de320e23ac | 324 | /** |
| Rhyme | 0:f0de320e23ac | 325 | * doGetAttribute |
| Rhyme | 0:f0de320e23ac | 326 | * |
| Rhyme | 0:f0de320e23ac | 327 | * The private version of getAttribute. This version actually calls sendCommand() to kick off the state machine and |
| Rhyme | 0:f0de320e23ac | 328 | * execute the operation. |
| Rhyme | 0:f0de320e23ac | 329 | */ |
| Rhyme | 0:f0de320e23ac | 330 | int afLib::doGetAttribute(uint8_t requestId, uint16_t attrId) { |
| Rhyme | 0:f0de320e23ac | 331 | if (_interrupts_pending > 0 || _writeCmd != NULL) { |
| Rhyme | 0:f0de320e23ac | 332 | return afERROR_BUSY; |
| Rhyme | 0:f0de320e23ac | 333 | } |
| Rhyme | 0:f0de320e23ac | 334 | |
| Rhyme | 0:f0de320e23ac | 335 | _writeCmd = new Command(requestId, MSG_TYPE_GET, attrId); |
| Rhyme | 0:f0de320e23ac | 336 | if (!_writeCmd->isValid()) { |
| Rhyme | 0:f0de320e23ac | 337 | SERIAL_PRINT_DBG_ASR("getAttribute invalid command:"); |
| Rhyme | 0:f0de320e23ac | 338 | _writeCmd->dumpBytes(); |
| Rhyme | 0:f0de320e23ac | 339 | _writeCmd->dump(); |
| Rhyme | 0:f0de320e23ac | 340 | delete (_writeCmd); |
| Rhyme | 0:f0de320e23ac | 341 | _writeCmd = NULL; |
| Rhyme | 0:f0de320e23ac | 342 | return afERROR_INVALID_COMMAND; |
| Rhyme | 0:f0de320e23ac | 343 | } |
| Rhyme | 0:f0de320e23ac | 344 | |
| Rhyme | 0:f0de320e23ac | 345 | _outstandingSetGetAttrId = attrId; |
| Rhyme | 0:f0de320e23ac | 346 | |
| Rhyme | 0:f0de320e23ac | 347 | // Start the transmission. |
| Rhyme | 0:f0de320e23ac | 348 | sendCommand(); |
| Rhyme | 0:f0de320e23ac | 349 | |
| Rhyme | 0:f0de320e23ac | 350 | return afSUCCESS; |
| Rhyme | 0:f0de320e23ac | 351 | } |
| Rhyme | 0:f0de320e23ac | 352 | |
| Rhyme | 0:f0de320e23ac | 353 | /** |
| Rhyme | 0:f0de320e23ac | 354 | * doSetAttribute |
| Rhyme | 0:f0de320e23ac | 355 | * |
| Rhyme | 0:f0de320e23ac | 356 | * The private version of setAttribute. This version actually calls sendCommand() to kick off the state machine and |
| Rhyme | 0:f0de320e23ac | 357 | * execute the operation. |
| Rhyme | 0:f0de320e23ac | 358 | */ |
| Rhyme | 0:f0de320e23ac | 359 | int afLib::doSetAttribute(uint8_t requestId, uint16_t attrId, uint16_t valueLen, uint8_t *value) { |
| Rhyme | 0:f0de320e23ac | 360 | if (_interrupts_pending > 0 || _writeCmd != NULL) { |
| Rhyme | 0:f0de320e23ac | 361 | return afERROR_BUSY; |
| Rhyme | 0:f0de320e23ac | 362 | } |
| Rhyme | 0:f0de320e23ac | 363 | _writeCmd = new Command(requestId, MSG_TYPE_SET, attrId, valueLen, value); |
| Rhyme | 0:f0de320e23ac | 364 | if (!_writeCmd->isValid()) { |
| Rhyme | 0:f0de320e23ac | 365 | SERIAL_PRINT_DBG_ASR("setAttributeComplete invalid command:"); |
| Rhyme | 0:f0de320e23ac | 366 | _writeCmd->dumpBytes(); |
| Rhyme | 0:f0de320e23ac | 367 | _writeCmd->dump(); |
| Rhyme | 0:f0de320e23ac | 368 | delete (_writeCmd); |
| Rhyme | 0:f0de320e23ac | 369 | _writeCmd = NULL; |
| Rhyme | 0:f0de320e23ac | 370 | return afERROR_INVALID_COMMAND; |
| Rhyme | 0:f0de320e23ac | 371 | } |
| Rhyme | 0:f0de320e23ac | 372 | |
| Rhyme | 0:f0de320e23ac | 373 | _outstandingSetGetAttrId = attrId; |
| Rhyme | 0:f0de320e23ac | 374 | |
| Rhyme | 0:f0de320e23ac | 375 | // Start the transmission. |
| Rhyme | 0:f0de320e23ac | 376 | sendCommand(); |
| Rhyme | 0:f0de320e23ac | 377 | |
| Rhyme | 0:f0de320e23ac | 378 | return afSUCCESS; |
| Rhyme | 0:f0de320e23ac | 379 | } |
| Rhyme | 0:f0de320e23ac | 380 | |
| Rhyme | 0:f0de320e23ac | 381 | /** |
| Rhyme | 0:f0de320e23ac | 382 | * doUpdateAttribute |
| Rhyme | 0:f0de320e23ac | 383 | * |
| Rhyme | 0:f0de320e23ac | 384 | * setAttribute calls on MCU attributes turn into updateAttribute calls. See documentation on the SPI protocol for |
| Rhyme | 0:f0de320e23ac | 385 | * more information. This method calls sendCommand() to kick off the state machine and execute the operation. |
| Rhyme | 0:f0de320e23ac | 386 | */ |
| Rhyme | 0:f0de320e23ac | 387 | int afLib::doUpdateAttribute(uint8_t requestId, uint16_t attrId, uint8_t status, uint16_t valueLen, uint8_t *value) { |
| Rhyme | 0:f0de320e23ac | 388 | if (_interrupts_pending > 0 || _writeCmd != NULL) { |
| Rhyme | 0:f0de320e23ac | 389 | return afERROR_BUSY; |
| Rhyme | 0:f0de320e23ac | 390 | } |
| Rhyme | 0:f0de320e23ac | 391 | |
| Rhyme | 0:f0de320e23ac | 392 | _writeCmd = new Command(requestId, MSG_TYPE_UPDATE, attrId, status, 3 /* MCU Set it */, valueLen, value); |
| Rhyme | 0:f0de320e23ac | 393 | if (!_writeCmd->isValid()) { |
| Rhyme | 0:f0de320e23ac | 394 | SERIAL_PRINT_DBG_ASR("updateAttribute invalid command:"); |
| Rhyme | 0:f0de320e23ac | 395 | _writeCmd->dumpBytes(); |
| Rhyme | 0:f0de320e23ac | 396 | _writeCmd->dump(); |
| Rhyme | 0:f0de320e23ac | 397 | delete (_writeCmd); |
| Rhyme | 0:f0de320e23ac | 398 | return afERROR_INVALID_COMMAND; |
| Rhyme | 0:f0de320e23ac | 399 | } |
| Rhyme | 0:f0de320e23ac | 400 | |
| Rhyme | 0:f0de320e23ac | 401 | // Start the transmission. |
| Rhyme | 0:f0de320e23ac | 402 | sendCommand(); |
| Rhyme | 0:f0de320e23ac | 403 | |
| Rhyme | 0:f0de320e23ac | 404 | return afSUCCESS; |
| Rhyme | 0:f0de320e23ac | 405 | } |
| Rhyme | 0:f0de320e23ac | 406 | |
| Rhyme | 0:f0de320e23ac | 407 | /** |
| Rhyme | 0:f0de320e23ac | 408 | * parseCommand |
| Rhyme | 0:f0de320e23ac | 409 | * |
| Rhyme | 0:f0de320e23ac | 410 | * A debug method for parsing a string into a command. This is not required for library operation and is only supplied |
| Rhyme | 0:f0de320e23ac | 411 | * as an example of how to execute attribute operations from a command line interface. |
| Rhyme | 0:f0de320e23ac | 412 | */ |
| Rhyme | 0:f0de320e23ac | 413 | #ifdef ATTRIBUTE_CLI |
| Rhyme | 0:f0de320e23ac | 414 | int afLib::parseCommand(const char *cmd) { |
| Rhyme | 0:f0de320e23ac | 415 | if (_interrupts_pending > 0 || _writeCmd != NULL) { |
| Rhyme | 0:f0de320e23ac | 416 | _theLog->print("Busy: "); |
| Rhyme | 0:f0de320e23ac | 417 | _theLog->print(_interrupts_pending); |
| Rhyme | 0:f0de320e23ac | 418 | _theLog->print(", "); |
| Rhyme | 0:f0de320e23ac | 419 | _theLog->println(_writeCmd != NULL); |
| Rhyme | 0:f0de320e23ac | 420 | return afERROR_BUSY; |
| Rhyme | 0:f0de320e23ac | 421 | } |
| Rhyme | 0:f0de320e23ac | 422 | |
| Rhyme | 0:f0de320e23ac | 423 | int reqId = _requestId++; |
| Rhyme | 0:f0de320e23ac | 424 | _writeCmd = new Command(_theLog,reqId, cmd); |
| Rhyme | 0:f0de320e23ac | 425 | if (!_writeCmd->isValid()) { |
| Rhyme | 0:f0de320e23ac | 426 | _theLog->print("BAD: "); |
| Rhyme | 0:f0de320e23ac | 427 | _theLog->println(cmd); |
| Rhyme | 0:f0de320e23ac | 428 | _writeCmd->dumpBytes(); |
| Rhyme | 0:f0de320e23ac | 429 | _writeCmd->dump(); |
| Rhyme | 0:f0de320e23ac | 430 | delete (_writeCmd); |
| Rhyme | 0:f0de320e23ac | 431 | _writeCmd = NULL; |
| Rhyme | 0:f0de320e23ac | 432 | return afERROR_INVALID_COMMAND; |
| Rhyme | 0:f0de320e23ac | 433 | } |
| Rhyme | 0:f0de320e23ac | 434 | |
| Rhyme | 0:f0de320e23ac | 435 | // Start the transmission. |
| Rhyme | 0:f0de320e23ac | 436 | sendCommand(); |
| Rhyme | 0:f0de320e23ac | 437 | |
| Rhyme | 0:f0de320e23ac | 438 | return afSUCCESS; |
| Rhyme | 0:f0de320e23ac | 439 | } |
| Rhyme | 0:f0de320e23ac | 440 | #endif |
| Rhyme | 0:f0de320e23ac | 441 | |
| Rhyme | 0:f0de320e23ac | 442 | /** |
| Rhyme | 0:f0de320e23ac | 443 | * runStateMachine |
| Rhyme | 0:f0de320e23ac | 444 | * |
| Rhyme | 0:f0de320e23ac | 445 | * The state machine for afLib. This state machine is responsible for implementing the KSP SPI protocol and executing |
| Rhyme | 0:f0de320e23ac | 446 | * attribute operations. |
| Rhyme | 0:f0de320e23ac | 447 | * This method is run: |
| Rhyme | 0:f0de320e23ac | 448 | * 1. In response to receiving an interrupt from the ASR-1. |
| Rhyme | 0:f0de320e23ac | 449 | * 2. When an attribute operation is pulled out of the queue and executed. |
| Rhyme | 0:f0de320e23ac | 450 | */ |
| Rhyme | 0:f0de320e23ac | 451 | void afLib::runStateMachine(void) { |
| Rhyme | 0:f0de320e23ac | 452 | if (_interrupts_pending > 0) { |
| Rhyme | 0:f0de320e23ac | 453 | switch (_state) { |
| Rhyme | 0:f0de320e23ac | 454 | case STATE_IDLE: |
| Rhyme | 0:f0de320e23ac | 455 | //deathWish.attach(&afLib::kick_the_bucket,10); |
| Rhyme | 0:f0de320e23ac | 456 | onStateIdle(); |
| Rhyme | 0:f0de320e23ac | 457 | return; |
| Rhyme | 0:f0de320e23ac | 458 | |
| Rhyme | 0:f0de320e23ac | 459 | case STATE_STATUS_SYNC: |
| Rhyme | 0:f0de320e23ac | 460 | onStateSync(); |
| Rhyme | 0:f0de320e23ac | 461 | break; |
| Rhyme | 0:f0de320e23ac | 462 | |
| Rhyme | 0:f0de320e23ac | 463 | case STATE_STATUS_ACK: |
| Rhyme | 0:f0de320e23ac | 464 | onStateAck(); |
| Rhyme | 0:f0de320e23ac | 465 | break; |
| Rhyme | 0:f0de320e23ac | 466 | |
| Rhyme | 0:f0de320e23ac | 467 | case STATE_SEND_BYTES: |
| Rhyme | 0:f0de320e23ac | 468 | onStateSendBytes(); |
| Rhyme | 0:f0de320e23ac | 469 | break; |
| Rhyme | 0:f0de320e23ac | 470 | |
| Rhyme | 0:f0de320e23ac | 471 | case STATE_RECV_BYTES: |
| Rhyme | 0:f0de320e23ac | 472 | onStateRecvBytes(); |
| Rhyme | 0:f0de320e23ac | 473 | break; |
| Rhyme | 0:f0de320e23ac | 474 | |
| Rhyme | 0:f0de320e23ac | 475 | case STATE_CMD_COMPLETE: |
| Rhyme | 0:f0de320e23ac | 476 | onStateCmdComplete(); |
| Rhyme | 0:f0de320e23ac | 477 | break; |
| Rhyme | 0:f0de320e23ac | 478 | } |
| Rhyme | 0:f0de320e23ac | 479 | |
| Rhyme | 0:f0de320e23ac | 480 | updateIntsPending(-1); |
| Rhyme | 0:f0de320e23ac | 481 | } else { |
| Rhyme | 0:f0de320e23ac | 482 | if (syncRetries > 0 && syncRetries < MAX_SYNC_RETRIES && checkLastSync->read_ms() - lastSync > 1000) { |
| Rhyme | 0:f0de320e23ac | 483 | updateIntsPending(1); |
| Rhyme | 0:f0de320e23ac | 484 | } else if (syncRetries >= MAX_SYNC_RETRIES) { |
| Rhyme | 0:f0de320e23ac | 485 | SERIAL_PRINT_DBG_ASR("No response from ASR-1 - does profile have MCU enabled?\n"); |
| Rhyme | 0:f0de320e23ac | 486 | #if defined(TARGET_KL25Z) |
| Rhyme | 0:f0de320e23ac | 487 | // WatchDogWrapper::getSelf()->kick_the_bucket(); |
| Rhyme | 0:f0de320e23ac | 488 | #endif //TARGET_KL25Z |
| Rhyme | 0:f0de320e23ac | 489 | syncRetries = 0; |
| Rhyme | 0:f0de320e23ac | 490 | _state = STATE_IDLE; |
| Rhyme | 0:f0de320e23ac | 491 | } |
| Rhyme | 0:f0de320e23ac | 492 | } |
| Rhyme | 0:f0de320e23ac | 493 | } |
| Rhyme | 0:f0de320e23ac | 494 | |
| Rhyme | 0:f0de320e23ac | 495 | /** |
| Rhyme | 0:f0de320e23ac | 496 | * onStateIdle |
| Rhyme | 0:f0de320e23ac | 497 | * |
| Rhyme | 0:f0de320e23ac | 498 | * If there is a command to be written, update the bytes to send. Otherwise we're sending a zero-sync message. |
| Rhyme | 0:f0de320e23ac | 499 | * Either way advance the state to send a sync message. |
| Rhyme | 0:f0de320e23ac | 500 | */ |
| Rhyme | 0:f0de320e23ac | 501 | void afLib::onStateIdle(void) { |
| Rhyme | 0:f0de320e23ac | 502 | if (_writeCmd != NULL) { |
| Rhyme | 0:f0de320e23ac | 503 | // Include 2 bytes for length |
| Rhyme | 0:f0de320e23ac | 504 | _bytesToSend = _writeCmd->getSize() + 2; |
| Rhyme | 0:f0de320e23ac | 505 | } else { |
| Rhyme | 0:f0de320e23ac | 506 | _bytesToSend = 0; |
| Rhyme | 0:f0de320e23ac | 507 | } |
| Rhyme | 0:f0de320e23ac | 508 | _state = STATE_STATUS_SYNC; |
| Rhyme | 0:f0de320e23ac | 509 | printState(_state); |
| Rhyme | 0:f0de320e23ac | 510 | } |
| Rhyme | 0:f0de320e23ac | 511 | |
| Rhyme | 0:f0de320e23ac | 512 | /** |
| Rhyme | 0:f0de320e23ac | 513 | * onStateSync |
| Rhyme | 0:f0de320e23ac | 514 | * |
| Rhyme | 0:f0de320e23ac | 515 | * Write a sync message over SPI to let the ASR-1 know that we want to send some data. |
| Rhyme | 0:f0de320e23ac | 516 | * Check for a "collision" which occurs if the ASR-1 is trying to send us data at the same time. |
| Rhyme | 0:f0de320e23ac | 517 | */ |
| Rhyme | 0:f0de320e23ac | 518 | void afLib::onStateSync(void) { |
| Rhyme | 0:f0de320e23ac | 519 | int result; |
| Rhyme | 0:f0de320e23ac | 520 | |
| Rhyme | 0:f0de320e23ac | 521 | _txStatus->setAck(false); |
| Rhyme | 0:f0de320e23ac | 522 | _txStatus->setBytesToSend(_bytesToSend); |
| Rhyme | 0:f0de320e23ac | 523 | _txStatus->setBytesToRecv(0); |
| Rhyme | 0:f0de320e23ac | 524 | |
| Rhyme | 0:f0de320e23ac | 525 | result = exchangeStatus(_txStatus, _rxStatus); |
| Rhyme | 0:f0de320e23ac | 526 | |
| Rhyme | 0:f0de320e23ac | 527 | if (result == afSUCCESS && _rxStatus->isValid() && inSync(_txStatus, _rxStatus)) { |
| Rhyme | 0:f0de320e23ac | 528 | syncRetries = 0; // Flag that sync completed. |
| Rhyme | 0:f0de320e23ac | 529 | _state = STATE_STATUS_ACK; |
| Rhyme | 0:f0de320e23ac | 530 | if (_txStatus->getBytesToSend() == 0 && _rxStatus->getBytesToRecv() > 0) { |
| Rhyme | 0:f0de320e23ac | 531 | _bytesToRecv = _rxStatus->getBytesToRecv(); |
| Rhyme | 0:f0de320e23ac | 532 | } |
| Rhyme | 0:f0de320e23ac | 533 | } else { |
| Rhyme | 0:f0de320e23ac | 534 | // Try resending the preamble |
| Rhyme | 0:f0de320e23ac | 535 | _state = STATE_STATUS_SYNC; |
| Rhyme | 0:f0de320e23ac | 536 | lastSync = checkLastSync->read_ms(); |
| Rhyme | 0:f0de320e23ac | 537 | syncRetries++; |
| Rhyme | 0:f0de320e23ac | 538 | // _txStatus->dumpBytes(); |
| Rhyme | 0:f0de320e23ac | 539 | // _rxStatus->dumpBytes(); |
| Rhyme | 0:f0de320e23ac | 540 | } |
| Rhyme | 0:f0de320e23ac | 541 | printState(_state); |
| Rhyme | 0:f0de320e23ac | 542 | } |
| Rhyme | 0:f0de320e23ac | 543 | |
| Rhyme | 0:f0de320e23ac | 544 | /** |
| Rhyme | 0:f0de320e23ac | 545 | * onStateAck |
| Rhyme | 0:f0de320e23ac | 546 | * |
| Rhyme | 0:f0de320e23ac | 547 | * Acknowledge the previous sync message and advance the state. |
| Rhyme | 0:f0de320e23ac | 548 | * If there are bytes to send, advance to send bytes state. |
| Rhyme | 0:f0de320e23ac | 549 | * If there are bytes to receive, advance to receive bytes state. |
| Rhyme | 0:f0de320e23ac | 550 | * Otherwise it was a zero-sync so advance to command complete. |
| Rhyme | 0:f0de320e23ac | 551 | */ |
| Rhyme | 0:f0de320e23ac | 552 | void afLib::onStateAck(void) { |
| Rhyme | 0:f0de320e23ac | 553 | int result; |
| Rhyme | 0:f0de320e23ac | 554 | |
| Rhyme | 0:f0de320e23ac | 555 | _txStatus->setAck(true); |
| Rhyme | 0:f0de320e23ac | 556 | _txStatus->setBytesToRecv(_rxStatus->getBytesToRecv()); |
| Rhyme | 0:f0de320e23ac | 557 | _bytesToRecv = _rxStatus->getBytesToRecv(); |
| Rhyme | 0:f0de320e23ac | 558 | result = writeStatus(_txStatus); |
| Rhyme | 0:f0de320e23ac | 559 | if (result != afSUCCESS) { |
| Rhyme | 0:f0de320e23ac | 560 | _state = STATE_STATUS_SYNC; |
| Rhyme | 0:f0de320e23ac | 561 | printState(_state); |
| Rhyme | 0:f0de320e23ac | 562 | return; |
| Rhyme | 0:f0de320e23ac | 563 | } |
| Rhyme | 0:f0de320e23ac | 564 | if (_bytesToSend > 0) { |
| Rhyme | 0:f0de320e23ac | 565 | _writeBufferLen = (uint16_t) _writeCmd->getSize(); |
| Rhyme | 0:f0de320e23ac | 566 | _writeBuffer = new uint8_t[_bytesToSend]; |
| Rhyme | 0:f0de320e23ac | 567 | memcpy(_writeBuffer, (uint8_t * ) & _writeBufferLen, 2); |
| Rhyme | 0:f0de320e23ac | 568 | _writeCmd->getBytes(&_writeBuffer[2]); |
| Rhyme | 0:f0de320e23ac | 569 | _state = STATE_SEND_BYTES; |
| Rhyme | 0:f0de320e23ac | 570 | } else if (_bytesToRecv > 0) { |
| Rhyme | 0:f0de320e23ac | 571 | _state = STATE_RECV_BYTES; |
| Rhyme | 0:f0de320e23ac | 572 | } else { |
| Rhyme | 0:f0de320e23ac | 573 | _state = STATE_CMD_COMPLETE; |
| Rhyme | 0:f0de320e23ac | 574 | } |
| Rhyme | 0:f0de320e23ac | 575 | printState(_state); |
| Rhyme | 0:f0de320e23ac | 576 | } |
| Rhyme | 0:f0de320e23ac | 577 | |
| Rhyme | 0:f0de320e23ac | 578 | /** |
| Rhyme | 0:f0de320e23ac | 579 | * onStateSendBytes |
| Rhyme | 0:f0de320e23ac | 580 | * |
| Rhyme | 0:f0de320e23ac | 581 | * Send the required number of bytes to the ASR-1 and then advance to command complete. |
| Rhyme | 0:f0de320e23ac | 582 | */ |
| Rhyme | 0:f0de320e23ac | 583 | void afLib::onStateSendBytes(void) { |
| Rhyme | 0:f0de320e23ac | 584 | // _theLog->print("send bytes: "); _theLog->println(_bytesToSend); |
| Rhyme | 0:f0de320e23ac | 585 | sendBytes(); |
| Rhyme | 0:f0de320e23ac | 586 | |
| Rhyme | 0:f0de320e23ac | 587 | if (_bytesToSend == 0) { |
| Rhyme | 0:f0de320e23ac | 588 | _writeBufferLen = 0; |
| Rhyme | 0:f0de320e23ac | 589 | delete[] (_writeBuffer); //wsugi delete (_writeBuffer); |
| Rhyme | 0:f0de320e23ac | 590 | _writeBuffer = NULL; |
| Rhyme | 0:f0de320e23ac | 591 | _state = STATE_CMD_COMPLETE; |
| Rhyme | 0:f0de320e23ac | 592 | printState(_state); |
| Rhyme | 0:f0de320e23ac | 593 | } |
| Rhyme | 0:f0de320e23ac | 594 | } |
| Rhyme | 0:f0de320e23ac | 595 | |
| Rhyme | 0:f0de320e23ac | 596 | /** |
| Rhyme | 0:f0de320e23ac | 597 | * onStateRecvBytes |
| Rhyme | 0:f0de320e23ac | 598 | * |
| Rhyme | 0:f0de320e23ac | 599 | * Receive the required number of bytes from the ASR-1 and then advance to command complete. |
| Rhyme | 0:f0de320e23ac | 600 | */ |
| Rhyme | 0:f0de320e23ac | 601 | void afLib::onStateRecvBytes(void) { |
| Rhyme | 0:f0de320e23ac | 602 | // _theLog->print("receive bytes: "); _theLog->println(_bytesToRecv); |
| Rhyme | 0:f0de320e23ac | 603 | recvBytes(); |
| Rhyme | 0:f0de320e23ac | 604 | if (_bytesToRecv == 0) { |
| Rhyme | 0:f0de320e23ac | 605 | _state = STATE_CMD_COMPLETE; |
| Rhyme | 0:f0de320e23ac | 606 | printState(_state); |
| Rhyme | 0:f0de320e23ac | 607 | _readCmd = new Command(_readBufferLen, &_readBuffer[2]); |
| Rhyme | 0:f0de320e23ac | 608 | delete[] (_readBuffer); //wsugi delete (_readBuffer); |
| Rhyme | 0:f0de320e23ac | 609 | _readBuffer = NULL; |
| Rhyme | 0:f0de320e23ac | 610 | } |
| Rhyme | 0:f0de320e23ac | 611 | } |
| Rhyme | 0:f0de320e23ac | 612 | |
| Rhyme | 0:f0de320e23ac | 613 | /** |
| Rhyme | 0:f0de320e23ac | 614 | * onStateCmdComplete |
| Rhyme | 0:f0de320e23ac | 615 | * |
| Rhyme | 0:f0de320e23ac | 616 | * Call the appropriate sketch callback to report the result of the command. |
| Rhyme | 0:f0de320e23ac | 617 | * Clear the command object and go back to waiting for the next interrupt or command. |
| Rhyme | 0:f0de320e23ac | 618 | */ |
| Rhyme | 0:f0de320e23ac | 619 | void afLib::onStateCmdComplete(void) { |
| Rhyme | 0:f0de320e23ac | 620 | _state = STATE_IDLE; |
| Rhyme | 0:f0de320e23ac | 621 | printState(_state); |
| Rhyme | 0:f0de320e23ac | 622 | if (_readCmd != NULL) { |
| Rhyme | 0:f0de320e23ac | 623 | uint8_t *val = new uint8_t[_readCmd->getValueLen()]; |
| Rhyme | 0:f0de320e23ac | 624 | _readCmd->getValue(val); |
| Rhyme | 0:f0de320e23ac | 625 | |
| Rhyme | 0:f0de320e23ac | 626 | switch (_readCmd->getCommand()) { |
| Rhyme | 0:f0de320e23ac | 627 | case MSG_TYPE_SET: |
| Rhyme | 0:f0de320e23ac | 628 | _onAttrSet(_readCmd->getReqId(), _readCmd->getAttrId(), _readCmd->getValueLen(), val); |
| Rhyme | 0:f0de320e23ac | 629 | break; |
| Rhyme | 0:f0de320e23ac | 630 | |
| Rhyme | 0:f0de320e23ac | 631 | case MSG_TYPE_UPDATE: |
| Rhyme | 0:f0de320e23ac | 632 | if (_readCmd->getAttrId() == _outstandingSetGetAttrId) { |
| Rhyme | 0:f0de320e23ac | 633 | _outstandingSetGetAttrId = 0; |
| Rhyme | 0:f0de320e23ac | 634 | } |
| Rhyme | 0:f0de320e23ac | 635 | _onAttrSetComplete(_readCmd->getReqId(), _readCmd->getAttrId(), _readCmd->getValueLen(), val); |
| Rhyme | 0:f0de320e23ac | 636 | break; |
| Rhyme | 0:f0de320e23ac | 637 | |
| Rhyme | 0:f0de320e23ac | 638 | default: |
| Rhyme | 0:f0de320e23ac | 639 | break; |
| Rhyme | 0:f0de320e23ac | 640 | } |
| Rhyme | 0:f0de320e23ac | 641 | delete[] (val); //wsugi delete (val); |
| Rhyme | 0:f0de320e23ac | 642 | delete (_readCmd); |
| Rhyme | 0:f0de320e23ac | 643 | _readCmdOffset = 0; |
| Rhyme | 0:f0de320e23ac | 644 | _readCmd = NULL; |
| Rhyme | 0:f0de320e23ac | 645 | } |
| Rhyme | 0:f0de320e23ac | 646 | |
| Rhyme | 0:f0de320e23ac | 647 | if (_writeCmd != NULL) { |
| Rhyme | 0:f0de320e23ac | 648 | // Fake a callback here for MCU attributes as we don't get one from the module. |
| Rhyme | 0:f0de320e23ac | 649 | if (_writeCmd->getCommand() == MSG_TYPE_UPDATE && IS_MCU_ATTR(_writeCmd->getAttrId())) { |
| Rhyme | 0:f0de320e23ac | 650 | _onAttrSetComplete(_writeCmd->getReqId(), _writeCmd->getAttrId(), _writeCmd->getValueLen(), _writeCmd->getValueP()); |
| Rhyme | 0:f0de320e23ac | 651 | } |
| Rhyme | 0:f0de320e23ac | 652 | delete (_writeCmd); |
| Rhyme | 0:f0de320e23ac | 653 | _writeCmdOffset = 0; |
| Rhyme | 0:f0de320e23ac | 654 | _writeCmd = NULL; |
| Rhyme | 0:f0de320e23ac | 655 | } |
| Rhyme | 0:f0de320e23ac | 656 | } |
| Rhyme | 0:f0de320e23ac | 657 | |
| Rhyme | 0:f0de320e23ac | 658 | /** |
| Rhyme | 0:f0de320e23ac | 659 | * exchangeStatus |
| Rhyme | 0:f0de320e23ac | 660 | * |
| Rhyme | 0:f0de320e23ac | 661 | * Write a status command object to the ASR-1 and clock in a status object from the ASR-1 at the same time. |
| Rhyme | 0:f0de320e23ac | 662 | */ |
| Rhyme | 0:f0de320e23ac | 663 | int afLib::exchangeStatus(StatusCommand *tx, StatusCommand *rx) { |
| Rhyme | 0:f0de320e23ac | 664 | int result = afSUCCESS; |
| Rhyme | 0:f0de320e23ac | 665 | uint16_t len = tx->getSize(); |
| Rhyme | 0:f0de320e23ac | 666 | int bytes[len]; |
| Rhyme | 0:f0de320e23ac | 667 | char rbytes[len+1]; |
| Rhyme | 0:f0de320e23ac | 668 | int index = 0; |
| Rhyme | 0:f0de320e23ac | 669 | tx->getBytes(bytes); |
| Rhyme | 0:f0de320e23ac | 670 | |
| Rhyme | 0:f0de320e23ac | 671 | // _theSPI->beginSPI(); |
| Rhyme | 0:f0de320e23ac | 672 | |
| Rhyme | 0:f0de320e23ac | 673 | for (int i=0;i<len;i++) |
| Rhyme | 0:f0de320e23ac | 674 | { |
| Rhyme | 0:f0de320e23ac | 675 | rbytes[i]=bytes[i]; |
| Rhyme | 0:f0de320e23ac | 676 | } |
| Rhyme | 0:f0de320e23ac | 677 | rbytes[len]=tx->getChecksum(); |
| Rhyme | 0:f0de320e23ac | 678 | |
| Rhyme | 0:f0de320e23ac | 679 | printTransaction((uint8_t*)rbytes,len+1); |
| Rhyme | 0:f0de320e23ac | 680 | |
| Rhyme | 0:f0de320e23ac | 681 | _theSPI->beginSPI(); |
| Rhyme | 0:f0de320e23ac | 682 | _theSPI->transfer(rbytes,len+1); |
| Rhyme | 0:f0de320e23ac | 683 | _theSPI->endSPI(); |
| Rhyme | 0:f0de320e23ac | 684 | |
| Rhyme | 0:f0de320e23ac | 685 | printTransaction((uint8_t*)rbytes,len+1); |
| Rhyme | 0:f0de320e23ac | 686 | |
| Rhyme | 0:f0de320e23ac | 687 | uint8_t cmd = bytes[index++]; |
| Rhyme | 0:f0de320e23ac | 688 | if (cmd != 0x30 && cmd != 0x31) { |
| Rhyme | 0:f0de320e23ac | 689 | SERIAL_PRINT_DBG_ASR("exchangeStatus bad cmd: 0x%02x\n",cmd); |
| Rhyme | 0:f0de320e23ac | 690 | result = afERROR_INVALID_COMMAND; |
| Rhyme | 0:f0de320e23ac | 691 | } |
| Rhyme | 0:f0de320e23ac | 692 | |
| Rhyme | 0:f0de320e23ac | 693 | rx->setBytesToSend(rbytes[index + 0] | (rbytes[index + 1] << 8)); |
| Rhyme | 0:f0de320e23ac | 694 | rx->setBytesToRecv(rbytes[index + 2] | (rbytes[index + 3] << 8)); |
| Rhyme | 0:f0de320e23ac | 695 | rx->setChecksum(rbytes[index+4]); |
| Rhyme | 0:f0de320e23ac | 696 | //_theSPI->endSPI(); |
| Rhyme | 0:f0de320e23ac | 697 | return result; |
| Rhyme | 0:f0de320e23ac | 698 | } |
| Rhyme | 0:f0de320e23ac | 699 | |
| Rhyme | 0:f0de320e23ac | 700 | /** |
| Rhyme | 0:f0de320e23ac | 701 | * inSync |
| Rhyme | 0:f0de320e23ac | 702 | * |
| Rhyme | 0:f0de320e23ac | 703 | * Check to make sure the Arduino and the ASR-1 aren't trying to send data at the same time. |
| Rhyme | 0:f0de320e23ac | 704 | * Return true only if there is no collision. |
| Rhyme | 0:f0de320e23ac | 705 | */ |
| Rhyme | 0:f0de320e23ac | 706 | bool afLib::inSync(StatusCommand *tx, StatusCommand *rx) { |
| Rhyme | 0:f0de320e23ac | 707 | return (tx->getBytesToSend() == 0 && rx->getBytesToRecv() == 0) || |
| Rhyme | 0:f0de320e23ac | 708 | (tx->getBytesToSend() > 0 && rx->getBytesToRecv() == 0) || |
| Rhyme | 0:f0de320e23ac | 709 | (tx->getBytesToSend() == 0 && rx->getBytesToRecv() > 0); |
| Rhyme | 0:f0de320e23ac | 710 | } |
| Rhyme | 0:f0de320e23ac | 711 | |
| Rhyme | 0:f0de320e23ac | 712 | /** |
| Rhyme | 0:f0de320e23ac | 713 | * writeStatus |
| Rhyme | 0:f0de320e23ac | 714 | * |
| Rhyme | 0:f0de320e23ac | 715 | * Write a status command to the ASR-1 and ignore the result. If you want to read bytes at the same time, use |
| Rhyme | 0:f0de320e23ac | 716 | * exchangeStatus instead. |
| Rhyme | 0:f0de320e23ac | 717 | */ |
| Rhyme | 0:f0de320e23ac | 718 | int afLib::writeStatus(StatusCommand *c) { |
| Rhyme | 0:f0de320e23ac | 719 | int result = afSUCCESS; |
| Rhyme | 0:f0de320e23ac | 720 | uint16_t len = c->getSize(); |
| Rhyme | 0:f0de320e23ac | 721 | int bytes[len]; |
| Rhyme | 0:f0de320e23ac | 722 | char rbytes[len+1]; |
| Rhyme | 0:f0de320e23ac | 723 | int index = 0; |
| Rhyme | 0:f0de320e23ac | 724 | c->getBytes(bytes); |
| Rhyme | 0:f0de320e23ac | 725 | |
| Rhyme | 0:f0de320e23ac | 726 | _theSPI->beginSPI(); |
| Rhyme | 0:f0de320e23ac | 727 | |
| Rhyme | 0:f0de320e23ac | 728 | for (int i=0;i<len;i++) |
| Rhyme | 0:f0de320e23ac | 729 | { |
| Rhyme | 0:f0de320e23ac | 730 | rbytes[i]=bytes[i]; |
| Rhyme | 0:f0de320e23ac | 731 | } |
| Rhyme | 0:f0de320e23ac | 732 | rbytes[len]=c->getChecksum(); |
| Rhyme | 0:f0de320e23ac | 733 | printTransaction((uint8_t*)rbytes,len+1); |
| Rhyme | 0:f0de320e23ac | 734 | _theSPI->transfer(rbytes,len+1); |
| Rhyme | 0:f0de320e23ac | 735 | printTransaction((uint8_t*)rbytes,len+1); |
| Rhyme | 0:f0de320e23ac | 736 | uint8_t cmd = rbytes[index++]; |
| Rhyme | 0:f0de320e23ac | 737 | if (cmd != 0x30 && cmd != 0x31) { |
| Rhyme | 0:f0de320e23ac | 738 | SERIAL_PRINT_DBG_ASR("writeStatus bad cmd: 0x%02x\n",cmd); |
| Rhyme | 0:f0de320e23ac | 739 | result = afERROR_INVALID_COMMAND; |
| Rhyme | 0:f0de320e23ac | 740 | } |
| Rhyme | 0:f0de320e23ac | 741 | |
| Rhyme | 0:f0de320e23ac | 742 | |
| Rhyme | 0:f0de320e23ac | 743 | _theSPI->endSPI(); |
| Rhyme | 0:f0de320e23ac | 744 | |
| Rhyme | 0:f0de320e23ac | 745 | // c->dump(); |
| Rhyme | 0:f0de320e23ac | 746 | // c->dumpBytes(); |
| Rhyme | 0:f0de320e23ac | 747 | |
| Rhyme | 0:f0de320e23ac | 748 | return result; |
| Rhyme | 0:f0de320e23ac | 749 | } |
| Rhyme | 0:f0de320e23ac | 750 | |
| Rhyme | 0:f0de320e23ac | 751 | /** |
| Rhyme | 0:f0de320e23ac | 752 | * sendBytes |
| Rhyme | 0:f0de320e23ac | 753 | * |
| Rhyme | 0:f0de320e23ac | 754 | * Send the specified number of data bytes to the ASR-1. Do this in chunks of SPI_FRAME_LEN bytes. |
| Rhyme | 0:f0de320e23ac | 755 | */ |
| Rhyme | 0:f0de320e23ac | 756 | void afLib::sendBytes() { |
| Rhyme | 0:f0de320e23ac | 757 | uint16_t len = _bytesToSend > SPI_FRAME_LEN ? SPI_FRAME_LEN : _bytesToSend; |
| Rhyme | 0:f0de320e23ac | 758 | uint8_t bytes[SPI_FRAME_LEN]; |
| Rhyme | 0:f0de320e23ac | 759 | memset(bytes, 0xff, sizeof(bytes)); |
| Rhyme | 0:f0de320e23ac | 760 | |
| Rhyme | 0:f0de320e23ac | 761 | memcpy(bytes, &_writeBuffer[_writeCmdOffset], len); |
| Rhyme | 0:f0de320e23ac | 762 | |
| Rhyme | 0:f0de320e23ac | 763 | _theSPI->beginSPI(); |
| Rhyme | 0:f0de320e23ac | 764 | printTransaction(bytes,len+1); |
| Rhyme | 0:f0de320e23ac | 765 | _theSPI->transfer((char *)bytes,len); |
| Rhyme | 0:f0de320e23ac | 766 | printTransaction(bytes,len+1); |
| Rhyme | 0:f0de320e23ac | 767 | _theSPI->endSPI(); |
| Rhyme | 0:f0de320e23ac | 768 | |
| Rhyme | 0:f0de320e23ac | 769 | // dumpBytes("Sending:", len, bytes); |
| Rhyme | 0:f0de320e23ac | 770 | |
| Rhyme | 0:f0de320e23ac | 771 | _writeCmdOffset += len; |
| Rhyme | 0:f0de320e23ac | 772 | _bytesToSend -= len; |
| Rhyme | 0:f0de320e23ac | 773 | } |
| Rhyme | 0:f0de320e23ac | 774 | |
| Rhyme | 0:f0de320e23ac | 775 | /** |
| Rhyme | 0:f0de320e23ac | 776 | * recvBytes |
| Rhyme | 0:f0de320e23ac | 777 | * |
| Rhyme | 0:f0de320e23ac | 778 | * Receive the specified number of data bytes from the ASR-1. Do this in chunks of SPI_FRAME_LEN bytes. |
| Rhyme | 0:f0de320e23ac | 779 | */ |
| Rhyme | 0:f0de320e23ac | 780 | void afLib::recvBytes() { |
| Rhyme | 0:f0de320e23ac | 781 | uint16_t len = _bytesToRecv > SPI_FRAME_LEN ? SPI_FRAME_LEN : _bytesToRecv; |
| Rhyme | 0:f0de320e23ac | 782 | |
| Rhyme | 0:f0de320e23ac | 783 | if (_readCmdOffset == 0) { |
| Rhyme | 0:f0de320e23ac | 784 | _readBufferLen = _bytesToRecv; |
| Rhyme | 0:f0de320e23ac | 785 | _readBuffer = new uint8_t[_readBufferLen]; |
| Rhyme | 0:f0de320e23ac | 786 | } |
| Rhyme | 0:f0de320e23ac | 787 | |
| Rhyme | 0:f0de320e23ac | 788 | _theSPI->beginSPI(); |
| Rhyme | 0:f0de320e23ac | 789 | |
| Rhyme | 0:f0de320e23ac | 790 | |
| Rhyme | 0:f0de320e23ac | 791 | char * start =(char*)_readBuffer + _readCmdOffset; |
| Rhyme | 0:f0de320e23ac | 792 | printTransaction((uint8_t*)start,len+1); |
| Rhyme | 0:f0de320e23ac | 793 | _theSPI->transfer(start,len); |
| Rhyme | 0:f0de320e23ac | 794 | printTransaction((uint8_t*)start,len+1); |
| Rhyme | 0:f0de320e23ac | 795 | |
| Rhyme | 0:f0de320e23ac | 796 | _theSPI->endSPI(); |
| Rhyme | 0:f0de320e23ac | 797 | |
| Rhyme | 0:f0de320e23ac | 798 | // dumpBytes("Receiving:", len, _readBuffer); |
| Rhyme | 0:f0de320e23ac | 799 | |
| Rhyme | 0:f0de320e23ac | 800 | _readCmdOffset += len; |
| Rhyme | 0:f0de320e23ac | 801 | _bytesToRecv -= len; |
| Rhyme | 0:f0de320e23ac | 802 | } |
| Rhyme | 0:f0de320e23ac | 803 | |
| Rhyme | 0:f0de320e23ac | 804 | /** |
| Rhyme | 0:f0de320e23ac | 805 | * isIdle |
| Rhyme | 0:f0de320e23ac | 806 | * |
| Rhyme | 0:f0de320e23ac | 807 | * Provide a way for the sketch to know if we're idle. Returns true if there are no attribute operations in progress. |
| Rhyme | 0:f0de320e23ac | 808 | */ |
| Rhyme | 0:f0de320e23ac | 809 | bool afLib::isIdle() { |
| Rhyme | 0:f0de320e23ac | 810 | return _interrupts_pending == 0 && _state == STATE_IDLE && _outstandingSetGetAttrId == 0; |
| Rhyme | 0:f0de320e23ac | 811 | } |
| Rhyme | 0:f0de320e23ac | 812 | |
| Rhyme | 0:f0de320e23ac | 813 | /** |
| Rhyme | 0:f0de320e23ac | 814 | * These methods are required to disable/enable interrupts for the Linux version of afLib. |
| Rhyme | 0:f0de320e23ac | 815 | * They are no-ops on Arduino. |
| Rhyme | 0:f0de320e23ac | 816 | */ |
| Rhyme | 0:f0de320e23ac | 817 | #ifndef ARDUINO |
| Rhyme | 0:f0de320e23ac | 818 | void noInterrupts(){} |
| Rhyme | 0:f0de320e23ac | 819 | void interrupts(){} |
| Rhyme | 0:f0de320e23ac | 820 | #endif |
| Rhyme | 0:f0de320e23ac | 821 | |
| Rhyme | 0:f0de320e23ac | 822 | void afLib::mcuISR() { |
| Rhyme | 0:f0de320e23ac | 823 | // _theLog->println("mcu"); |
| Rhyme | 0:f0de320e23ac | 824 | updateIntsPending(1); |
| Rhyme | 0:f0de320e23ac | 825 | } |
| Rhyme | 0:f0de320e23ac | 826 | |
| Rhyme | 0:f0de320e23ac | 827 | /**************************************************************************** |
| Rhyme | 0:f0de320e23ac | 828 | * Queue Methods * |
| Rhyme | 0:f0de320e23ac | 829 | ****************************************************************************/ |
| Rhyme | 0:f0de320e23ac | 830 | /** |
| Rhyme | 0:f0de320e23ac | 831 | * queueInit |
| Rhyme | 0:f0de320e23ac | 832 | * |
| Rhyme | 0:f0de320e23ac | 833 | * Create a small queue to prevent flooding the ASR-1 with attribute operations. |
| Rhyme | 0:f0de320e23ac | 834 | * The initial size is small to allow running on small boards like UNO. |
| Rhyme | 0:f0de320e23ac | 835 | * Size can be increased on larger boards. |
| Rhyme | 0:f0de320e23ac | 836 | */ |
| Rhyme | 0:f0de320e23ac | 837 | void afLib::queueInit() { |
| Rhyme | 0:f0de320e23ac | 838 | for (int i = 0; i < REQUEST_QUEUE_SIZE; i++) { |
| Rhyme | 0:f0de320e23ac | 839 | _requestQueue[i].p_value = NULL; |
| Rhyme | 0:f0de320e23ac | 840 | } |
| Rhyme | 0:f0de320e23ac | 841 | } |
| Rhyme | 0:f0de320e23ac | 842 | |
| Rhyme | 0:f0de320e23ac | 843 | /** |
| Rhyme | 0:f0de320e23ac | 844 | * queuePut |
| Rhyme | 0:f0de320e23ac | 845 | * |
| Rhyme | 0:f0de320e23ac | 846 | * Add an item to the end of the queue. Return an error if we're out of space in the queue. |
| Rhyme | 0:f0de320e23ac | 847 | */ |
| Rhyme | 0:f0de320e23ac | 848 | int afLib::queuePut(uint8_t messageType, uint8_t requestId, const uint16_t attributeId, uint16_t valueLen, |
| Rhyme | 0:f0de320e23ac | 849 | const uint8_t *value) { |
| Rhyme | 0:f0de320e23ac | 850 | for (int i = 0; i < REQUEST_QUEUE_SIZE; i++) { |
| Rhyme | 0:f0de320e23ac | 851 | if (_requestQueue[i].p_value == NULL) { |
| Rhyme | 0:f0de320e23ac | 852 | _requestQueue[i].messageType = messageType; |
| Rhyme | 0:f0de320e23ac | 853 | _requestQueue[i].attrId = attributeId; |
| Rhyme | 0:f0de320e23ac | 854 | _requestQueue[i].requestId = requestId; |
| Rhyme | 0:f0de320e23ac | 855 | _requestQueue[i].valueLen = valueLen; |
| Rhyme | 0:f0de320e23ac | 856 | _requestQueue[i].p_value = new uint8_t[valueLen]; |
| Rhyme | 0:f0de320e23ac | 857 | memcpy(_requestQueue[i].p_value, value, valueLen); |
| Rhyme | 0:f0de320e23ac | 858 | return afSUCCESS; |
| Rhyme | 0:f0de320e23ac | 859 | } |
| Rhyme | 0:f0de320e23ac | 860 | } |
| Rhyme | 0:f0de320e23ac | 861 | |
| Rhyme | 0:f0de320e23ac | 862 | return afERROR_QUEUE_OVERFLOW; |
| Rhyme | 0:f0de320e23ac | 863 | } |
| Rhyme | 0:f0de320e23ac | 864 | |
| Rhyme | 0:f0de320e23ac | 865 | /** |
| Rhyme | 0:f0de320e23ac | 866 | * queueGet |
| Rhyme | 0:f0de320e23ac | 867 | * |
| Rhyme | 0:f0de320e23ac | 868 | * Pull and return the oldest item from the queue. Return an error if the queue is empty. |
| Rhyme | 0:f0de320e23ac | 869 | */ |
| Rhyme | 0:f0de320e23ac | 870 | int afLib::queueGet(uint8_t *messageType, uint8_t *requestId, uint16_t *attributeId, uint16_t *valueLen, |
| Rhyme | 0:f0de320e23ac | 871 | uint8_t **value) { |
| Rhyme | 0:f0de320e23ac | 872 | for (int i = 0; i < REQUEST_QUEUE_SIZE; i++) { |
| Rhyme | 0:f0de320e23ac | 873 | if (_requestQueue[i].p_value != NULL) { |
| Rhyme | 0:f0de320e23ac | 874 | *messageType = _requestQueue[i].messageType; |
| Rhyme | 0:f0de320e23ac | 875 | *attributeId = _requestQueue[i].attrId; |
| Rhyme | 0:f0de320e23ac | 876 | *requestId = _requestQueue[i].requestId; |
| Rhyme | 0:f0de320e23ac | 877 | *valueLen = _requestQueue[i].valueLen; |
| Rhyme | 0:f0de320e23ac | 878 | *value = new uint8_t[*valueLen]; |
| Rhyme | 0:f0de320e23ac | 879 | memcpy(*value, _requestQueue[i].p_value, *valueLen); |
| Rhyme | 0:f0de320e23ac | 880 | delete[] (_requestQueue[i].p_value); //wsugi delete (_requestQueue[i].p_value); |
| Rhyme | 0:f0de320e23ac | 881 | _requestQueue[i].p_value = NULL; |
| Rhyme | 0:f0de320e23ac | 882 | return afSUCCESS; |
| Rhyme | 0:f0de320e23ac | 883 | } |
| Rhyme | 0:f0de320e23ac | 884 | } |
| Rhyme | 0:f0de320e23ac | 885 | |
| Rhyme | 0:f0de320e23ac | 886 | return afERROR_QUEUE_UNDERFLOW; |
| Rhyme | 0:f0de320e23ac | 887 | } |
| Rhyme | 0:f0de320e23ac | 888 | |
| Rhyme | 0:f0de320e23ac | 889 | /**************************************************************************** |
| Rhyme | 0:f0de320e23ac | 890 | * Debug Methods * |
| Rhyme | 0:f0de320e23ac | 891 | ****************************************************************************/ |
| Rhyme | 0:f0de320e23ac | 892 | /** |
| Rhyme | 0:f0de320e23ac | 893 | * dumpBytes |
| Rhyme | 0:f0de320e23ac | 894 | * |
| Rhyme | 0:f0de320e23ac | 895 | * Dump a byte buffer to the debug log. |
| Rhyme | 0:f0de320e23ac | 896 | */ |
| Rhyme | 0:f0de320e23ac | 897 | void afLib::dumpBytes(char *label, int len, uint8_t *bytes) { |
| Rhyme | 0:f0de320e23ac | 898 | SERIAL_PRINT_DBG_ASR("%s\n",label); |
| Rhyme | 0:f0de320e23ac | 899 | for (int i = 0; i < len; i++) { |
| Rhyme | 0:f0de320e23ac | 900 | if (i > 0) { |
| Rhyme | 0:f0de320e23ac | 901 | SERIAL_PRINT_DBG_ASR(", "); |
| Rhyme | 0:f0de320e23ac | 902 | } |
| Rhyme | 0:f0de320e23ac | 903 | uint8_t b = bytes[i] & 0xff; |
| Rhyme | 0:f0de320e23ac | 904 | |
| Rhyme | 0:f0de320e23ac | 905 | if (b < 0x10) { |
| Rhyme | 0:f0de320e23ac | 906 | SERIAL_PRINT_DBG_ASR("0x02x", b); |
| Rhyme | 0:f0de320e23ac | 907 | } else { |
| Rhyme | 0:f0de320e23ac | 908 | //_theLog->print("0x"); |
| Rhyme | 0:f0de320e23ac | 909 | SERIAL_PRINT_DBG_ASR("0x02x",b);//, HEX); |
| Rhyme | 0:f0de320e23ac | 910 | } |
| Rhyme | 0:f0de320e23ac | 911 | } |
| Rhyme | 0:f0de320e23ac | 912 | SERIAL_PRINT_DBG_ASR("\n"); |
| Rhyme | 0:f0de320e23ac | 913 | } |
| Rhyme | 0:f0de320e23ac | 914 | |
| Rhyme | 0:f0de320e23ac | 915 | /** |
| Rhyme | 0:f0de320e23ac | 916 | * printState |
| Rhyme | 0:f0de320e23ac | 917 | * |
| Rhyme | 0:f0de320e23ac | 918 | * Print the current state of the afLib state machine. For debugging, just remove the return statement. |
| Rhyme | 0:f0de320e23ac | 919 | */ |
| Rhyme | 0:f0de320e23ac | 920 | void afLib::printState(int state) { |
| Rhyme | 0:f0de320e23ac | 921 | // return; |
| Rhyme | 0:f0de320e23ac | 922 | switch (state) { |
| Rhyme | 0:f0de320e23ac | 923 | case STATE_IDLE: |
| Rhyme | 0:f0de320e23ac | 924 | SERIAL_PRINT_DBG_ASR("STATE_IDLE\n"); |
| Rhyme | 0:f0de320e23ac | 925 | break; |
| Rhyme | 0:f0de320e23ac | 926 | case STATE_STATUS_SYNC: |
| Rhyme | 0:f0de320e23ac | 927 | SERIAL_PRINT_DBG_ASR("STATE_STATUS_SYNC\n"); |
| Rhyme | 0:f0de320e23ac | 928 | break; |
| Rhyme | 0:f0de320e23ac | 929 | case STATE_STATUS_ACK: |
| Rhyme | 0:f0de320e23ac | 930 | SERIAL_PRINT_DBG_ASR("STATE_STATUS_ACK\n"); |
| Rhyme | 0:f0de320e23ac | 931 | break; |
| Rhyme | 0:f0de320e23ac | 932 | case STATE_SEND_BYTES: |
| Rhyme | 0:f0de320e23ac | 933 | SERIAL_PRINT_DBG_ASR("STATE_SEND_BYTES\n"); |
| Rhyme | 0:f0de320e23ac | 934 | break; |
| Rhyme | 0:f0de320e23ac | 935 | case STATE_RECV_BYTES: |
| Rhyme | 0:f0de320e23ac | 936 | SERIAL_PRINT_DBG_ASR("STATE_RECV_BYTES\n"); |
| Rhyme | 0:f0de320e23ac | 937 | break; |
| Rhyme | 0:f0de320e23ac | 938 | case STATE_CMD_COMPLETE: |
| Rhyme | 0:f0de320e23ac | 939 | SERIAL_PRINT_DBG_ASR("STATE_CMD_COMPLETE\n"); |
| Rhyme | 0:f0de320e23ac | 940 | break; |
| Rhyme | 0:f0de320e23ac | 941 | default: |
| Rhyme | 0:f0de320e23ac | 942 | SERIAL_PRINT_DBG_ASR("Unknown State!\n"); |
| Rhyme | 0:f0de320e23ac | 943 | break; |
| Rhyme | 0:f0de320e23ac | 944 | } |
| Rhyme | 0:f0de320e23ac | 945 | } |
| Rhyme | 0:f0de320e23ac | 946 | |
| Rhyme | 0:f0de320e23ac | 947 | void afLib::printTransaction(uint8_t *rbytes, int len) |
| Rhyme | 0:f0de320e23ac | 948 | { |
| Rhyme | 0:f0de320e23ac | 949 | //return; |
| Rhyme | 0:f0de320e23ac | 950 | int i = 0; |
| Rhyme | 0:f0de320e23ac | 951 | for(;i<=len;++i) |
| Rhyme | 0:f0de320e23ac | 952 | { |
| Rhyme | 0:f0de320e23ac | 953 | SERIAL_PRINT_DBG_ASR("0x%02x:",rbytes[i]); |
| Rhyme | 0:f0de320e23ac | 954 | } |
| Rhyme | 0:f0de320e23ac | 955 | SERIAL_PRINT_DBG_ASR("\n"); |
| Rhyme | 0:f0de320e23ac | 956 | } |