SAKURA Internet / SakuraIO Featured

Dependents:   patlite_sakuraio sakuraio_lte_firmwareupdater shownet2017-iinebutton patlite_sakuraio_stack ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SakuraIO.cpp Source File

SakuraIO.cpp

00001 /* SAKURA Internet IoT Communication Module Library for mbed
00002  *
00003  * The MIT License (MIT)
00004  *
00005  * Copyright (c) SAKURA Internet Inc.
00006  *
00007  * Permission is hereby granted, free of charge, to any person obtaining a copy
00008  * of this software and associated documentation files (the "Software"),
00009  * to deal in the Software without restriction, including without limitation
00010  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00011  * and/or sell copies of the Software, and to permit persons to whom the Software
00012  * is furnished to do so, subject to the following conditions:
00013  *
00014  * The above copyright notice and this permission notice shall be included
00015  * in all copies or substantial portions of the Software.
00016  *
00017  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00018  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00020  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00021  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00022  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00023  */
00024 
00025 #include "mbed.h"
00026 #include "SakuraIO.h"
00027 #include "SakuraIO/commands.h"
00028 #include "SakuraIO/debug.h"
00029 
00030 #define delay(ms) wait_ms(ms)
00031 
00032 uint8_t SakuraIO::executeCommand(uint8_t cmd,uint8_t requestLength, uint8_t *request, uint8_t *responseLength, uint8_t *response)
00033 {
00034   uint8_t parity = 0x00;
00035   uint8_t result = 0x00;
00036   uint8_t reservedResponseLength, tmpResponse, receivedResponseLength;
00037 
00038   dbgln("executeCommand");
00039 
00040   this->begin();
00041 
00042   // request
00043   this->sendByte(cmd);
00044   this->sendByte(requestLength);
00045   parity = cmd ^ requestLength;
00046   for(int16_t i=0; i<requestLength; i++){
00047     parity ^= request[i];
00048     this->sendByte(request[i]);
00049   }
00050   this->sendByte(parity);
00051   //this->finishSending();
00052 
00053   reservedResponseLength = 0;
00054   if(responseLength != NULL){
00055     reservedResponseLength = *responseLength;
00056   }
00057 
00058   delay(10);
00059 
00060   // response
00061   this->startReceive(reservedResponseLength+3);
00062   result = this->receiveByte();
00063   if(result != CMD_ERROR_NONE){
00064     dbgln("Invalid status");
00065     this->end();
00066     return result;
00067   }
00068   receivedResponseLength = this->receiveByte();
00069   if(responseLength != NULL){
00070     *responseLength = receivedResponseLength;
00071   }
00072 
00073   parity = result ^ receivedResponseLength;
00074   for(int16_t i=0; i<receivedResponseLength; i++){
00075     tmpResponse = this->receiveByte();
00076     parity ^= tmpResponse;
00077     if(response != NULL && i<reservedResponseLength){
00078       response[i] = tmpResponse;
00079     }
00080   }
00081   dbgln("Parity");
00082   uint8_t p = this->receiveByte(true);
00083   parity ^= p;
00084   dbg("Parity=");
00085   dbgln(p);
00086   if(parity != 0x00){
00087     result = CMD_ERROR_PARITY;
00088     dbgln("Invalid parity");
00089   }else{
00090     dbgln("Success");
00091   }
00092   //this->finishReceiving();
00093 
00094   this->end();
00095   return result;
00096 }
00097 
00098 /* Common Commands */
00099 
00100 uint8_t SakuraIO::getConnectionStatus(){
00101   uint8_t responseLength = 1;
00102   uint8_t response[1] = {0x00};
00103   if(executeCommand(CMD_GET_CONNECTION_STATUS, 0, NULL, &responseLength, response) != CMD_ERROR_NONE){
00104     return 0x7F;
00105   }
00106   return response[0];
00107 }
00108 
00109 uint8_t SakuraIO::getSignalQuality(){
00110   uint8_t responseLength = 1;
00111   uint8_t response[1] = {0x00};
00112 
00113   if(executeCommand(CMD_GET_SIGNAL_QUALITY, 0, NULL, &responseLength, response) != CMD_ERROR_NONE){
00114     return 0x00;
00115   }
00116   return response[0];
00117 }
00118 
00119 uint8_t SakuraIO::getSignalQuarity(){
00120   // deprecated
00121   return getSignalQuality();
00122 }
00123 
00124 uint64_t SakuraIO::getUnixtime(){
00125   uint8_t responseLength = 8;
00126   uint8_t response[8] = {0x00};
00127   if(executeCommand(CMD_GET_DATETIME, 0, NULL, &responseLength, response) != CMD_ERROR_NONE){
00128     return 0x00;
00129   }
00130   return *((uint64_t *)response);
00131 }
00132 
00133 uint8_t SakuraIO::echoback(uint8_t length, uint8_t *data, uint8_t *response){
00134   uint8_t responseLength = length;
00135   if(executeCommand(CMD_ECHO_BACK, length, data, &responseLength, response) != CMD_ERROR_NONE){
00136     return 0x00;
00137   }
00138   return responseLength;
00139 }
00140 
00141 /* IO Commands */
00142 
00143 uint16_t SakuraIO::getADC(uint8_t channel){
00144   uint8_t request[1] = {channel};
00145   uint8_t response[2] = {0x00};
00146   uint8_t responseLength = sizeof(response);
00147   if(executeCommand(CMD_READ_ADC, 1, request, &responseLength, response) != CMD_ERROR_NONE){
00148     return 0xffff;
00149   }
00150   return *((uint16_t *)response);
00151 }
00152 
00153 /* TX Commands */
00154 uint8_t SakuraIO::enqueueTxRaw(uint8_t ch, uint8_t type, uint8_t length, uint8_t *data, uint64_t offset){
00155   uint8_t request[18] = {0x00};
00156   uint8_t requestLength = 10;
00157   request[0] = ch;
00158   request[1] = type;
00159   for(uint8_t i=0;i<length;i++){
00160     request[2+i] = data[i];
00161   }
00162   if(offset != 0){
00163     requestLength = 18;
00164     for(uint8_t i=0;i<8;i++){
00165       request[10+i] = ((uint8_t *)&offset)[i];
00166     }
00167   }
00168   return executeCommand(CMD_TX_ENQUEUE, requestLength, request, NULL, NULL);
00169 }
00170 
00171 uint8_t SakuraIO::enqueueTx(uint8_t ch, int32_t value, uint64_t offset){
00172   return enqueueTxRaw(ch, 'i', 4, (uint8_t *)&value, offset);
00173 }
00174 
00175 uint8_t SakuraIO::enqueueTx(uint8_t ch, uint32_t value, uint64_t offset){
00176   return enqueueTxRaw(ch, 'I', 4, (uint8_t *)&value, offset);
00177 }
00178 
00179 uint8_t SakuraIO::enqueueTx(uint8_t ch, int64_t value, uint64_t offset){
00180   return enqueueTxRaw(ch, 'l', 8, (uint8_t *)&value, offset);
00181 }
00182 
00183 uint8_t SakuraIO::enqueueTx(uint8_t ch, uint64_t value, uint64_t offset){
00184   return enqueueTxRaw(ch, 'L', 8, (uint8_t *)&value, offset);
00185 }
00186 
00187 uint8_t SakuraIO::enqueueTx(uint8_t ch, float value, uint64_t offset){
00188   return enqueueTxRaw(ch, 'f', 4, (uint8_t *)&value, offset);
00189 }
00190 
00191 uint8_t SakuraIO::enqueueTx(uint8_t ch, double value, uint64_t offset){
00192   return enqueueTxRaw(ch, 'd', 8, (uint8_t *)&value, offset);
00193 }
00194 
00195 uint8_t SakuraIO::enqueueTx(uint8_t ch, uint8_t value[8], uint64_t offset){
00196   return enqueueTxRaw(ch, 'b', 8, (uint8_t *)value, offset);
00197 }
00198 
00199 uint8_t SakuraIO::enqueueTx(uint8_t ch, int32_t value){
00200   return enqueueTx(ch, value, (uint32_t)0);
00201 }
00202 
00203 uint8_t SakuraIO::enqueueTx(uint8_t ch, uint32_t value){
00204   return enqueueTx(ch, value, (uint32_t)0);
00205 }
00206 
00207 uint8_t SakuraIO::enqueueTx(uint8_t ch, int64_t value){
00208   return enqueueTx(ch, value, (uint32_t)0);
00209 }
00210 
00211 uint8_t SakuraIO::enqueueTx(uint8_t ch, uint64_t value){
00212   return enqueueTx(ch, value, (uint32_t)0);
00213 }
00214 
00215 uint8_t SakuraIO::enqueueTx(uint8_t ch, float value){
00216   return enqueueTx(ch, value, (uint32_t)0);
00217 }
00218 
00219 uint8_t SakuraIO::enqueueTx(uint8_t ch, double value){
00220   return enqueueTx(ch, value, (uint32_t)0);
00221 }
00222 
00223 uint8_t SakuraIO::enqueueTx(uint8_t ch, uint8_t value[8]){
00224   return enqueueTx(ch, value, (uint32_t)0);
00225 }
00226 
00227 uint8_t SakuraIO::sendImmediatelyRaw(uint8_t ch, uint8_t type, uint8_t length, uint8_t *data, uint64_t offset){
00228   uint8_t request[18] = {0x00};
00229   uint8_t requestLength = 10;
00230   request[0] = ch;
00231   request[1] = type;
00232   for(uint8_t i=0;i<length;i++){
00233     request[2+i] = data[i];
00234   }
00235   if(offset != 0){
00236     requestLength = 18;
00237     for(uint8_t i=0;i<8;i++){
00238       request[10+i] = ((uint8_t *)&offset)[i];
00239     }
00240   }
00241   return executeCommand(CMD_TX_SENDIMMED, requestLength, request, NULL, NULL);
00242 }
00243 
00244 uint8_t SakuraIO::sendImmediately(uint8_t ch, int32_t value, uint64_t offset){
00245   return sendImmediatelyRaw(ch, 'i', 4, (uint8_t *)&value, offset);
00246 }
00247 
00248 uint8_t SakuraIO::sendImmediately(uint8_t ch, uint32_t value, uint64_t offset){
00249   return sendImmediatelyRaw(ch, 'I', 4, (uint8_t *)&value, offset);
00250 }
00251 
00252 uint8_t SakuraIO::sendImmediately(uint8_t ch, int64_t value, uint64_t offset){
00253   return sendImmediatelyRaw(ch, 'l', 8, (uint8_t *)&value, offset);
00254 }
00255 
00256 uint8_t SakuraIO::sendImmediately(uint8_t ch, uint64_t value, uint64_t offset){
00257   return sendImmediatelyRaw(ch, 'L', 8, (uint8_t *)&value, offset);
00258 }
00259 
00260 uint8_t SakuraIO::sendImmediately(uint8_t ch, float value, uint64_t offset){
00261   return sendImmediatelyRaw(ch, 'f', 4, (uint8_t *)&value, offset);
00262 }
00263 
00264 uint8_t SakuraIO::sendImmediately(uint8_t ch, double value, uint64_t offset){
00265   return sendImmediatelyRaw(ch, 'd', 8, (uint8_t *)&value, offset);
00266 }
00267 
00268 uint8_t SakuraIO::sendImmediately(uint8_t ch, uint8_t value[8], uint64_t offset){
00269   return sendImmediatelyRaw(ch, 'b', 8, (uint8_t *)value, offset);
00270 }
00271 
00272 uint8_t SakuraIO::sendImmediately(uint8_t ch, int32_t value){
00273   return sendImmediately(ch, value, (uint32_t)0);
00274 }
00275 
00276 uint8_t SakuraIO::sendImmediately(uint8_t ch, uint32_t value){
00277   return sendImmediately(ch, value, (uint32_t)0);
00278 }
00279 
00280 uint8_t SakuraIO::sendImmediately(uint8_t ch, int64_t value){
00281   return sendImmediately(ch, value, (uint32_t)0);
00282 }
00283 
00284 uint8_t SakuraIO::sendImmediately(uint8_t ch, uint64_t value){
00285   return sendImmediately(ch, value, (uint32_t)0);
00286 }
00287 
00288 uint8_t SakuraIO::sendImmediately(uint8_t ch, float value){
00289   return sendImmediately(ch, value, (uint32_t)0);
00290 }
00291 
00292 uint8_t SakuraIO::sendImmediately(uint8_t ch, double value){
00293   return sendImmediately(ch, value, (uint32_t)0);
00294 }
00295 
00296 uint8_t SakuraIO::sendImmediately(uint8_t ch, uint8_t value[8]){
00297   return sendImmediately(ch, value, (uint32_t)0);
00298 }
00299 
00300 
00301 
00302 uint8_t SakuraIO::getTxQueueLength(uint8_t *available, uint8_t *queued){
00303   uint8_t response[2] = {0x00};
00304   uint8_t responseLength = 2;
00305   uint8_t ret = executeCommand(CMD_TX_LENGTH, 0, NULL, &responseLength, response);
00306   *available = response[0];
00307   *queued = response[1];
00308   return ret;
00309 }
00310 
00311 uint8_t SakuraIO::clearTx(){
00312   return executeCommand(CMD_TX_CLEAR, 0, NULL, NULL, NULL);
00313 }
00314 
00315 uint8_t SakuraIO::send(){
00316   return executeCommand(CMD_TX_SEND, 0, NULL, NULL, NULL);
00317 }
00318 
00319 uint8_t SakuraIO::getTxStatus(uint8_t *queue, uint8_t *immediate){
00320   uint8_t response[2] = {0x00};
00321   uint8_t responseLength = 2;
00322   uint8_t ret = executeCommand(CMD_TX_STAT, 0, NULL, &responseLength, response);
00323   *queue = response[0];
00324   *immediate = response[1];
00325   return ret;
00326 }
00327 
00328 /* RX Commands */
00329 
00330 uint8_t SakuraIO::dequeueRx(uint8_t *ch, uint8_t *type, uint8_t *value, int64_t *offset){
00331   uint8_t response[18] = {0x00};
00332   uint8_t responseLength = 18;
00333   uint8_t ret = executeCommand(CMD_RX_DEQUEUE, 0, NULL, &responseLength, response);
00334   if(ret != CMD_ERROR_NONE){
00335     return ret;
00336   }
00337 
00338   *ch = response[0];
00339   *type = response[1];
00340   for(uint8_t i=0; i<8; i++){
00341     value[i] = response[2+i];
00342   }
00343   for(uint8_t i=0; i<8; i++){
00344     ((uint8_t *)offset)[i] = response[10+i];
00345   }
00346 
00347   return ret;
00348 }
00349 
00350 uint8_t SakuraIO::peekRx(uint8_t *ch, uint8_t *type, uint8_t *value, int64_t *offset){
00351   uint8_t response[18] = {0x00};
00352   uint8_t responseLength = 18;
00353   uint8_t ret = executeCommand(CMD_RX_PEEK, 0, NULL, &responseLength, response);
00354   if(ret != CMD_ERROR_NONE){
00355     return ret;
00356   }
00357 
00358   *ch = response[0];
00359   *type = response[1];
00360   for(uint8_t i=0; i<8; i++){
00361     value[i] = response[2+i];
00362   }
00363   for(uint8_t i=0; i<8; i++){
00364     ((uint8_t *)offset)[i] = response[10+i];
00365   }
00366 
00367   return ret;
00368 }
00369 
00370 uint8_t SakuraIO::getRxQueueLength(uint8_t *available, uint8_t *queued){
00371   uint8_t response[2] = {0x00};
00372   uint8_t responseLength = 2;
00373   uint8_t ret = executeCommand(CMD_RX_LENGTH, 0, NULL, &responseLength, response);
00374   *available = response[0];
00375   *queued = response[1];
00376   return ret;
00377 }
00378 
00379 uint8_t SakuraIO::clearRx(){
00380   return executeCommand(CMD_RX_CLEAR, 0, NULL, NULL, NULL);
00381 }
00382 
00383 /* File command */
00384 uint8_t SakuraIO::startFileDownload(uint16_t fileId){
00385   return executeCommand(CMD_START_FILE_DOWNLOAD, 2, (uint8_t *)&fileId, NULL, NULL);
00386 }
00387 
00388 uint8_t SakuraIO::cancelFileDownload(){
00389   return executeCommand(CMD_CANCEL_FILE_DOWNLOAD, 0, NULL, NULL, NULL);
00390 }
00391 
00392 uint8_t SakuraIO::getFileMetaData(uint8_t *status, uint32_t *totalSize, uint64_t *timestamp, uint32_t *crc){
00393   uint8_t response[17] = {0x00};
00394   uint8_t responseLength = 17;
00395   uint8_t ret = executeCommand(CMD_GET_FILE_METADATA, 0, NULL, &responseLength, response);
00396   *status = response[0];
00397   *totalSize = *(uint32_t *)(response+1);
00398   *timestamp = *(uint64_t *)(response+5);
00399   *crc = *(uint32_t *)(response+13);
00400   return ret;
00401 }
00402 
00403 uint8_t SakuraIO::getFileDownloadStatus(uint8_t *status, uint32_t *currentSize){
00404   uint8_t response[5] = {0x00};
00405   uint8_t responseLength = 5;
00406   uint8_t ret = executeCommand(CMD_GET_FILE_DOWNLOAD_STATUS, 0, NULL, &responseLength, response);
00407   *status = response[0];
00408   *currentSize = *(uint32_t *)(response+1);
00409   return ret;
00410 }
00411 
00412 uint8_t SakuraIO::getFileData(uint8_t *size, uint8_t *data){
00413   return executeCommand(CMD_GET_FILE_DATA, 1, size, size, data);
00414 }
00415 
00416 /* Operation command */
00417 
00418 uint16_t SakuraIO::getProductID(){
00419   uint8_t response[2] = {0x00};
00420   uint8_t responseLength = 2;
00421   uint8_t ret = executeCommand(CMD_GET_PRODUCT_ID, 0, NULL, &responseLength, response);
00422   if(ret != CMD_ERROR_NONE){
00423     return 0x00;
00424   }
00425   return *((uint16_t *)response);
00426 }
00427 
00428 uint8_t SakuraIO::getUniqueID(char *data){
00429   uint8_t response[11] = {0x00};
00430   uint8_t responseLength = 10;
00431   uint8_t ret = executeCommand(CMD_GET_UNIQUE_ID, 0, NULL, &responseLength, response);
00432   if(ret != CMD_ERROR_NONE){
00433     return ret;
00434   }
00435   for(uint8_t i=0; i<responseLength; i++){
00436     data[i] = (char)response[i];
00437   }
00438   data[responseLength] = 0x00;
00439   return ret;
00440 }
00441 
00442 uint8_t SakuraIO::getFirmwareVersion(char *data){
00443   uint8_t response[33] = {0x00};
00444   uint8_t responseLength = 32;
00445   uint8_t ret = executeCommand(CMD_GET_FIRMWARE_VERSION, 0, NULL, &responseLength, response);
00446   if(ret != CMD_ERROR_NONE){
00447     return ret;
00448   }
00449   for(uint8_t i=0; i<responseLength; i++){
00450     data[i] = (char)response[i];
00451   }
00452   data[responseLength] = 0x00;
00453   return ret;
00454 }
00455 
00456 uint8_t SakuraIO::unlock(){
00457   uint8_t request[4] = {0x53, 0x6B, 0x72, 0x61};
00458   return executeCommand(CMD_UNLOCK, 4, request, NULL, NULL);
00459 }
00460 
00461 uint8_t SakuraIO::updateFirmware(){
00462   return executeCommand(CMD_UPDATE_FIRMWARE, 0, 0, NULL, NULL);
00463 }
00464 
00465 uint8_t SakuraIO::getFirmwareUpdateStatus(){
00466   uint8_t response[1] = {0x00};
00467   uint8_t responseLength = 1;
00468   if(executeCommand(CMD_GET_UPDATE_FIRMWARE_STATUS, 0, 0, &responseLength, response) != CMD_ERROR_NONE){
00469       return 0xff;
00470   }
00471   return response[0];
00472 }
00473 
00474 uint8_t SakuraIO::reset(){
00475   return executeCommand(CMD_SOFTWARE_RESET, 0, 0, NULL, NULL);
00476 }
00477 
00478 uint8_t SakuraIO::setPowerSaveMode(uint8_t mode)
00479 {
00480   uint8_t request[1] = {mode};
00481   return executeCommand(CMD_SET_POWER_SAVE_MODE, 1, request, NULL, NULL);
00482 }
00483 
00484 uint8_t SakuraIO::getPowerSaveMode()
00485 {
00486   uint8_t response[1] = {0x00};
00487   uint8_t responseLength = 1;
00488   if (executeCommand(CMD_GET_POWER_SAVE_MODE, 0, NULL, &responseLength, response) != CMD_ERROR_NONE) {
00489       return 0xff;
00490   }
00491   return response[0];    
00492 }
00493