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