こたまご chibiegg / SakuraIO

Fork of SakuraIO by SAKURA Internet

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 uint8_t SakuraIO::executeCommand(uint8_t cmd,uint8_t requestLength, uint8_t *request, uint8_t *responseLength, uint8_t *response)
00031 {
00032   uint8_t parity = 0x00;
00033   uint8_t result = 0x00;
00034   uint8_t tmpResponseLength, tmpResponse;
00035 
00036   dbgln("executeCommand");
00037 
00038   this->begin();
00039 
00040   // request
00041   this->sendByte(cmd);
00042   this->sendByte(requestLength);
00043   parity = cmd ^ requestLength;
00044   for(int16_t i=0; i<requestLength; i++){
00045     parity ^= request[i];
00046     this->sendByte(request[i]);
00047   }
00048   this->sendByte(parity);
00049   //this->finishSending();
00050 
00051   tmpResponseLength = 0;
00052   if(responseLength != NULL){
00053     tmpResponseLength = *responseLength;
00054   }
00055 
00056   wait_ms(10);
00057 
00058   // response
00059   this->startReceive(tmpResponseLength+3);
00060   result = this->receiveByte();
00061   if(result != CMD_ERROR_NONE){
00062     dbgln("Invalid status");
00063     this->end();
00064     return result;
00065   }
00066   tmpResponseLength = this->receiveByte();
00067   parity = result ^ tmpResponseLength;
00068   if(responseLength != NULL){
00069     if(*responseLength < tmpResponseLength){
00070       tmpResponseLength = *responseLength;
00071     }
00072     *responseLength = tmpResponseLength;
00073   }
00074   for(int16_t i=0; i<tmpResponseLength; i++){
00075     tmpResponse = this->receiveByte();
00076     parity ^= tmpResponse;
00077     if(response != NULL){
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::getTxQueueLength(uint8_t *available, uint8_t *queued){
00228   uint8_t response[2] = {0x00};
00229   uint8_t responseLength = 2;
00230   uint8_t ret = executeCommand(CMD_TX_LENGTH, 0, NULL, &responseLength, response);
00231   *available = response[0];
00232   *queued = response[1];
00233   return ret;
00234 }
00235 
00236 uint8_t SakuraIO::clearTx(){
00237   return executeCommand(CMD_TX_CLEAR, 0, NULL, NULL, NULL);
00238 }
00239 
00240 uint8_t SakuraIO::send(){
00241   return executeCommand(CMD_TX_SEND, 0, NULL, NULL, NULL);
00242 }
00243 
00244 uint8_t SakuraIO::getTxStatus(uint8_t *queue, uint8_t *immediate){
00245   uint8_t response[2] = {0x00};
00246   uint8_t responseLength = 2;
00247   uint8_t ret = executeCommand(CMD_TX_STAT, 0, NULL, &responseLength, response);
00248   *queue = response[0];
00249   *immediate = response[1];
00250   return ret;
00251 }
00252 
00253 /* RX Commands */
00254 
00255 uint8_t SakuraIO::dequeueRx(uint8_t *ch, uint8_t *type, uint8_t *value, int64_t *offset){
00256   uint8_t response[18] = {0x00};
00257   uint8_t responseLength = 18;
00258   uint8_t ret = executeCommand(CMD_RX_DEQUEUE, 0, NULL, &responseLength, response);
00259   if(ret != CMD_ERROR_NONE){
00260     return ret;
00261   }
00262 
00263   *ch = response[0];
00264   *type = response[1];
00265   for(uint8_t i=0; i<8; i++){
00266     value[i] = response[2+i];
00267   }
00268   for(uint8_t i=0; i<8; i++){
00269     ((uint8_t *)offset)[i] = response[10+i];
00270   }
00271 
00272   return ret;
00273 }
00274 
00275 uint8_t SakuraIO::peekRx(uint8_t *ch, uint8_t *type, uint8_t *value, int64_t *offset){
00276   uint8_t response[18] = {0x00};
00277   uint8_t responseLength = 18;
00278   uint8_t ret = executeCommand(CMD_RX_PEEK, 0, NULL, &responseLength, response);
00279   if(ret != CMD_ERROR_NONE){
00280     return ret;
00281   }
00282 
00283   *ch = response[0];
00284   *type = response[1];
00285   for(uint8_t i=0; i<8; i++){
00286     value[i] = response[2+i];
00287   }
00288   for(uint8_t i=0; i<8; i++){
00289     ((uint8_t *)offset)[i] = response[10+i];
00290   }
00291 
00292   return ret;
00293 }
00294 
00295 uint8_t SakuraIO::getRxQueueLength(uint8_t *available, uint8_t *queued){
00296   uint8_t response[2] = {0x00};
00297   uint8_t responseLength = 2;
00298   uint8_t ret = executeCommand(CMD_RX_LENGTH, 0, NULL, &responseLength, response);
00299   *available = response[0];
00300   *queued = response[1];
00301   return ret;
00302 }
00303 
00304 uint8_t SakuraIO::clearRx(){
00305   return executeCommand(CMD_RX_CLEAR, 0, NULL, NULL, NULL);
00306 }
00307 
00308 /* Operation command */
00309 
00310 uint16_t SakuraIO::getProductID(){
00311   uint8_t response[2] = {0x00};
00312   uint8_t responseLength = 2;
00313   uint8_t ret = executeCommand(CMD_GET_PRODUCT_ID, 0, NULL, &responseLength, response);
00314   if(ret != CMD_ERROR_NONE){
00315     return 0x00;
00316   }
00317   return *((uint16_t *)response);
00318 }
00319 
00320 uint8_t SakuraIO::getUniqueID(char *data){
00321   uint8_t response[11] = {0x00};
00322   uint8_t responseLength = 10;
00323   uint8_t ret = executeCommand(CMD_GET_UNIQUE_ID, 0, NULL, &responseLength, response);
00324   if(ret != CMD_ERROR_NONE){
00325     return ret;
00326   }
00327   for(uint8_t i=0; i<responseLength; i++){
00328     data[i] = (char)response[i];
00329   }
00330   data[responseLength] = 0x00;
00331   return ret;
00332 }
00333 
00334 uint8_t SakuraIO::getFirmwareVersion(char *data){
00335   uint8_t response[33] = {0x00};
00336   uint8_t responseLength = 32;
00337   uint8_t ret = executeCommand(CMD_GET_FIRMWARE_VERSION, 0, NULL, &responseLength, response);
00338   if(ret != CMD_ERROR_NONE){
00339     return ret;
00340   }
00341   for(uint8_t i=0; i<responseLength; i++){
00342     data[i] = (char)response[i];
00343   }
00344   data[responseLength] = 0x00;
00345   return ret;
00346 }
00347 
00348 uint8_t SakuraIO::unlock(){
00349   uint8_t request[4] = {0x53, 0x6B, 0x72, 0x61};
00350   return executeCommand(CMD_UNLOCK, 4, request, NULL, NULL);
00351 }
00352 
00353 uint8_t SakuraIO::updateFirmware(){
00354   return executeCommand(CMD_UPDATE_FIRMWARE, 0, 0, NULL, NULL);
00355 }
00356 
00357 uint8_t SakuraIO::getFirmwareUpdateStatus(){
00358   uint8_t response[1] = {0x00};
00359   uint8_t responseLength = 1;
00360   if(executeCommand(CMD_GET_UPDATE_FIRMWARE_STATUS, 0, 0, &responseLength, response) != CMD_ERROR_NONE){
00361       return 0xff;
00362   }
00363   return response[0];
00364 }
00365 
00366 uint8_t SakuraIO::reset(){
00367   return executeCommand(CMD_SOFTWARE_RESET, 0, 0, NULL, NULL);
00368 }