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