alan broad
/
carbon_v5_arm_studio
arm studio build
src/main.cpp
- Committer:
- alan1974
- Date:
- 2019-01-19
- Revision:
- 15:ed77b752eaa9
- Parent:
- 14:fc836a5a5d2f
- Child:
- 16:5cc10d804d49
File content as of revision 15:ed77b752eaa9:
#include "mbed.h" #include "global.h" #include "commI2C.h" #include "dot_util.h" #include "wbit_util.h" #include "multicast.h" #include "mDot.h" #include "RadioEvent.h" #include "ChannelPlans.h" #include "Lora.h" bool verbose = true; bool bRxDone = false; //true if callback function RxDone() triggered bool bDownLinkCntrFail = false; //true if callback function RxDone() triggered and bad downlink frame count bool bClassA = true; //false => Class C multicast mode //nvm storage params nvm nvmData; nvm *pNvmData = &nvmData; //======================================================================================================= // enable GPIO for scope trigger //======================================================================================================= //#define GPIO_ENABLE //======================================================================================================= // configure for either private (test only) or public network (standard) //======================================================================================================= //#define MT_PRIVATE_NETWORK //ENABLE THIS FOR PRIVATE NETWORK //======================================================================================================= //code api level and version //api_level: proc code will not run if api level (last two bytess) greater than what it expects //======================================================================================================= uint8_t api_level[4] = { 0x00, 0x00, 0x00, 0x03 }; //api-level, determines if xdot code works with proc code uint8_t ver_level[4] = { 0x00, 0x00, 0x00, 0x09 }; //updated for every code check-in //======================================================================================================= //configuring mbed pinsa; https://docs.mbed.com/docs/mbed-os-api-reference/en/latest/APIs/io/DigitalInOut/ // * these options must match the settings on your gateway // // * edit their values to match your configuration // // * frequency sub band is only relevant for the 915 bands // // * either the network name and passphrase can be used or // // the network ID (8 bytes) and KEY (16 bytes) // //======================================================================================================= static std::string network_name = "asdfqwer"; //not used static std::string network_passphrase = "zxcvasdf"; //not used #ifdef MT_PRIVATE_NETWORK static uint8_t frequency_sub_band = 4; static bool public_network = false; static uint8_t ack = 1; //0; #else uint8_t frequency_sub_band = 1; bool public_network = true; //false uint8_t ack = 1; //0; uint8_t link_check_treshold = 100; //5; #endif bool adr = false; //set adaptive data rate //======================================================================================================= // -need to add a delay between exiting i2c read->proc and before putting xdot to sleep to allow for final // xfr of bytes in i2c buffer to be xfrd to proc. If log output enabled then it causes enough delay when // it prints status info to make the delay ok. For now add this delay when both log enabled and disabled. int16_t wait_before_sleep_usec = 10000; //======================================================================================================= // deepsleep consumes slightly less current than sleep // sleep mode: IO state is maintained, RAM is retained, and application will resume after waking up // deepsleep mode: IOs float, RAM is lost, and application will start from beginning after waking up // if deep_sleep == true, device will enter deepsleep mode // asb: // no longer use deepsleep since we want to retain state // sleep uses only 1uA more current than deepsleep //======================================================================================================= static bool deep_sleep = false; //false; uint32_t packets_sent = 0; uint32_t acks_rcvd = 0; int8_t rssi =0; //rssi of last rcvd rx1/rx2 std::string eui = " "; static bool led_enabled = false; //true; //false; mDot* dot = NULL; lora::ChannelPlan* plan = NULL; uint8_t buf_xmt[BUFFER_SIZE_I2C]; //outgoing data uint8_t buf_rcv[BUFFER_SIZE_I2C]; //incoming data std::vector<uint8_t> upstream_packet; #ifdef GPIO_ENABLE DigitalInOut gpio1(PA_5); //scope debug PA-5 is connected to SW1 pads on Loren v04 and can be used for scope debug #endif Serial pc(USBTX, USBRX); //serial port output //================================================================================== //chksum //compute checksum over i2c buffer except for last byte (chksum byte) //================================================================================== uint8_t chksum_proc(uint8_t *bfr_xdot){ uint8_t i; uint8_t chksum = 0; for (i=0; i < BUFFER_SIZE_I2C-1;i++)chksum += bfr_xdot[i];//good code return chksum; } //================================================================================================= //cfg_network: // configure the network public/private and sub-band // bForceCfg : true => force a network cfg // false => only change if bPublic or sub_band have changed // bPublic : true if network is public, else private // sub_band: sub band number (1..8) // NOTE: THIS ONLY WORKS WHEN THE XDOT BOOTS UP. IT DOES NOT WORK WHEN TRYING TO CHANGE AFTER. // NOT SURE WHY...WHEN THE XDOT REJOINS IT SHOULD USE NEW SESSION SETTINGS... asb // //asb:dec 2017: try this later and see if it works:mdot.h: // int32_t setPublicNetwork(const bool& on); // bool getPublicNetwork(); // int32_t setFrequencySubBand(const uint8_t& band); //================================================================================================= bool cfg_network(bool bForceCfg,bool bPublic,uint8_t sub_band){ // if bForceCfg false and network parameters haven't changed then just exit if (!bForceCfg){ if(verbose)pc.printf("no configuration change needed subband the same"); if ((public_network ==bPublic) && (frequency_sub_band ==sub_band))return true; } if(verbose)pc.printf("changing to subband: %d\r\n",sub_band); // update network settings public_network = bPublic; frequency_sub_band =sub_band; // start from a well-known state logInfo("defaulting Dot configuration"); if (dot->getJoinMode() != mDot::OTA) { // update configuration if necessary logInfo("changing network join mode to OTA"); if (dot->setJoinMode(mDot::OTA) != mDot::MDOT_OK) { logError("failed to set network join mode to OTA"); return false; } } // in OTA and AUTO_OTA join modes, the credentials can be passed to the library as a name and passphrase or an ID and KEY // only one method or the other should be used! if (public_network){ update_ota_config_id_key(nvmData.key_AppEUI,nvmData.key_AppKey, frequency_sub_band, public_network, ack); logInfo("-------------- network configured for public access -----------------------------"); } else{ update_ota_config_name_phrase(network_name, network_passphrase, frequency_sub_band, public_network, ack); logInfo("-------------- network configured for private access -------------------------------"); } // configure network link check count // declares the Dot disconnected if no acks received within link_check_treshold transmits //update_network_link_check_config(3, 5); dot->setLinkCheckThreshold(link_check_treshold); return true; } //================================================================================================= //main() // main() runs in its own thread in the OS // (note the calls to wait below for delays) //================================================================================================= int main() { uint8_t i; RadioEvent events; //class to return info on rx pkts mDotEvent mdotevent; //used to get ping info???? //plan = new lora::ChannelPlan_US915(); static lora::ChannelPlan_US915 plan; #ifdef GPIO_ENABLE gpio1.output(); gpio1 =0; #endif pc.baud(115200); pc.printf("\r\n**********************************************************\r\n"); pc.printf("\r\n XDOT BOOT\r\n"); pc.printf("COMM api_level = <HEX> %x.%x.%x.%x\r\n",api_level[0],api_level[1],api_level[2],api_level[3]); pc.printf("COMM version = %x.%x.%x.%x\r\n",ver_level[0],ver_level[1],ver_level[2],ver_level[3]); pc.printf("**********************************************************\r\n"); //assert(plan); //dot = mDot::getInstance(plan); dot = mDot::getInstance(&plan); //assert(dot); //dot->setEvents(&events); nvmRead(pNvmData); if (pNvmData->bLogOutputOn == 0){ pc.printf("\r\nDISABLING TERMINAL OUTPUT\r\n"); dot->setLogLevel(mts::MTSLog::NONE_LEVEL); //doesn't work verbose = false; } else{ printNmvData(pNvmData); dot->setLogLevel((verbose) ? mts::MTSLog::TRACE_LEVEL : mts::MTSLog::TRACE_LEVEL); // TRACE_LEVEL , INFO_LEVEL } // getStandbyFlag() should return the state of the standby flag directly from the processor // Standby flag: This bit is set by hardware and cleared only by a POR/PDR (power on reset/power down reset) or by setting the CSBF bit in the PWR power control register (PWR_CR) // 0: Device has not been in Standby mode // 1: Device has been in Standby mode // The xDot should enter standby mode when deep sleep in invoked. So you should see the standby flag set if it came out of deep sleep. if (!dot->getStandbyFlag()) { //if 0 => power-up/reset which should always be the case at this point logInfo("mbed-os library version: %d", MBED_LIBRARY_VERSION); frequency_sub_band = dot->getFrequencySubBand(); printRadioCfg(); cfg_network(true,public_network,frequency_sub_band); //force network cfg, } else { // restore the saved session (join OTAA info) if the dot woke from deepsleep mode // useful to use with deepsleep because session info is otherwise lost when the dot enters deepsleep logInfo("restoring network session from NVM"); dot->restoreNetworkSession(); } //-------------------------------------------------------------------------------------------------------------------------------------------- // configure network link check count // declares the Dot disconnected if no acks received within link_check_treshold transmits //update_network_link_check_config(3, 5); dot->setLinkCheckThreshold(link_check_treshold); //---------------------------------------------------------------------------------------------------------------------------------------------- // save changes to configuration // logInfo("saving configuration"); eui = mts::Text::bin2hexString(dot->getDeviceId()).c_str(); if(verbose)pc.printf("\r\nEUI: %s\r\n",eui); bool joined = false; i2c_proc_init(); //init i2c comm sleep_wake_interrupt_only(deep_sleep); //wake on rising edge of wake signal from proc //scope test #ifdef GPIO_ENABLE gpio1 =1; #endif //============================================================================== // -loop here forever // -sleep until LORA_WAKE goes hi => proc ready to send i2c cmd // -start polling incoming i2c bus for proc cmd // -execute cmd // -take control of LORA_WAKE and toggle it hi to signal proc that xdot // ready to send i2c ack message // -go back to sleep //============================================================================== bool bPulseLoraWake = false; while(1) { if(verbose)pc.printf("\n\r***************************** "); switch (i2c_proc_comm()){ case I2C_WRITE: //xdot ack ->proc if(verbose)pc.printf("\n\r xdot ack -> proc done,going to sleep\n\r "); bPulseLoraWake = false; #ifdef GPIO_ENABLE gpio1 =0; #endif wait_us(wait_before_sleep_usec); //wait for i2c to complete data transfer before sleeping //#ifdef NOTYET if (!bClassA){ if(verbose)pc.printf("\n\r changed to class C, LISTEN ONLY \r\n"); wait(1800); // CLASS C MODE LISTEN ONLY !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! } //#endif else{ sleep_wake_interrupt_only(deep_sleep); //sleep until rising edge of wake signal from proc } #ifdef GPIO_ENABLE gpio1 =1; #endif if(verbose)pc.printf("\n\r lora wake detected -> monitoring i2c bus\n\r "); break; case I2C_READ: //xdot <- proc bPulseLoraWake = true; switch (buf_rcv[0]) { case XDOT_CMD_XMIT_PKT: pkt_upstrm *pUp= (pkt_upstrm*)&buf_rcv[0]; for (i=0; i < sizeof(buf_xmt);i++)buf_xmt[i] = 0xff; //bfr fill pkt_ack *pAck = (pkt_ack*)&buf_xmt[0]; pAck->ack = I2C_ACK_PROC; pAck->cmd = XDOT_CMD_XMIT_PKT; pAck->dataLen = pUp->dataLen; //data len of xmitted pkt if(verbose)pc.printf("\r\npkt to xmit data len: %d\r\n",pAck->dataLen); uint8_t chksum = chksum_proc(buf_rcv); if(verbose)pc.printf("\r\nI2C chksum rcvd/computer: %d/%d ",pUp->chksum,chksum); pAck->bXmitAttempted = 1; pAck->chksum_err = 0; if(pUp->chksum != chksum){ if(verbose)pc.printf(" chksum err, aborting xmit"); pAck->bXmitAttempted = 0; pAck->mdot_ret = XDOT_ERR_I2C_CHKSUM; pAck->chksum_err = 1; break; } //rev 0307 parameters if(verbose)pc.printf("\n\r setting application port %d ",pUp->appPort); //appPort not used in rev < 0307 dot->setAppPort(pUp->appPort); uint8_t linkThresholdCnt = pUp->linkThreshCnt; if(verbose)pc.printf("\r\n linkThreshCnt %d\r\n",linkThresholdCnt); dot->setLinkCheckThreshold(linkThresholdCnt); if (pUp->dataLen == 0){ //datalen non zero? pAck->bXmitAttempted = 0; break; } upstream_packet.clear(); //xfr data from incoming bfr to xmit bfr for (i=0; i< pUp->dataLen;i++) upstream_packet.push_back(pUp->txData[i]); if(verbose){ pc.printf("\r\n[TEST],Upstream Packet Received"); for(std::vector<uint8_t>::iterator it = upstream_packet.begin(); it != upstream_packet.end(); ++it) pc.printf(",0x%x", *it); pc.printf("\r\n"); // see i told you. } joined = dot->getNetworkJoinStatus(); //are we joined to Lorawan? pAck->joinAttempts = 0; //no attempts made yet to join pAck->bAck = 0; //won't know if we receive a lorawan ack until after xmit pAck->bAckdata = 0; //won't know if we receive a lorawan ack downstream data until after xmit pAck->rssi = 0; //if not rx1/rx2 then no RSSI value pAck->snr = 0; //if not rx1/rx2 then no SNR value if(!joined) { //if not previously joined, then need to join now pAck->bJoined = 0; if(verbose)pc.printf("\r\n----------- NETWORK NOT JOINED YET, WILL TRY TO JOIN %d TIMES\r\n",pUp->joinAttemps); joined = join_network_wbit(pUp->joinAttemps); //try joinAttemps times to join network pAck->joinAttempts = join_network_attempts_wbit(); //# of join attemps made pAck->mdot_ret = dot->send(upstream_packet); //<--------------------------------------- extra xmit ??????????????? if (!joined) if(verbose)pc.printf("\r\n----------- FAILED TO JOIN...GIVING UP\r\n"); // join network if not joined else { save_OTAA_session_keys(); plan.SetRx2DatarateIndex(8); //LORIOT FIX FOR RX2 & OTA !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ---> doesn't work here???? } } if (joined) { pAck->bJoined = 1; //we are joined to the network packets_sent++; bRxDone = false; //true if callback function RxDone() triggered bDownLinkCntrFail = false; //true if callback function RxDone() triggered and bad downlink frame count //send packet -> return code indicates results, send return code back to proc Dec14,2017 plan.SetRx2DatarateIndex(8); //LORIOT FIX FOR RX2 & OT --- work here????? pAck->mdot_ret = dot->send(upstream_packet); //xmit the pkt in blocking mode, return false if no ack if (verbose)printf("\n\rdata->send() return code: %d\r\n",pAck->mdot_ret); if (pAck->mdot_ret == mDot::MDOT_OK) { acks_rcvd++; pAck->bAck = 1; //we got a Rx1 or Rx2 ack mDot::rssi_stats rssiStats = dot->getRssiStats(); //rssi stat pAck->rssi = (int8_t)rssiStats.last; mDot::snr_stats snrStats = dot->getSnrStats(); //snr stat pAck->snr = (int8_t)snrStats.last; if (verbose)printf("\n\rdata->send()=true; ack:%d, rssi:%d snr:%d\r\n",pAck->bAck,pAck->rssi,pAck->snr); if (events.is_packet_received()){ //downstream data from the Rx1/Rx2 pkt? if (verbose)printf("\n\revents.is_packet_received = true\r\n"); pAck->bAckdata = 1; upstream_packet.clear(); upstream_packet = events.get_downstream_packet(); pAck->rxLen = upstream_packet.size(); pAck->appPort = events.port; if (pAck->rxLen > I2C_MAX_ACK_DATA){ if(verbose)pc.printf("\r\n got ack with pkt data too large.. rejected\r\n"); break; } if(verbose){ pc.printf("\r\n pkt data: "); for (i=0; i< pAck->rxLen;i++) { pAck->rxData[i]= upstream_packet[i]; pc.printf(" %x",pAck->rxData[i]); } } } //if downstream data rcvd else{ if (verbose)printf("\n\r ack rcvd without data\r\n"); } //else } //send() //rev 0308 parameters else { if (verbose)printf("\n\r no ack rcvd \r\n"); //could be some other error if ((pAck->mdot_ret != 0) && bRxDone) //chk if callback function triggered { if (bDownLinkCntrFail)pAck->mdot_ret = XDOT_ERR_FRAME_CNT; //bad downlink frame count return err code } } }//if joined break; case XDOT_CMD_SET_RADIO: if(verbose)pc.printf("\n\r proc cmd: CMD_SET_RADIO"); pkt_setradiodwn *pDwnRadio= (pkt_setradiodwn*)&buf_xmt[0]; pkt_setradioup *pUpRadio = (pkt_setradioup*)&buf_rcv[0]; pDwnRadio->ack = I2C_ACK_PROC; pDwnRadio->cmd = XDOT_CMD_SET_RADIO; if (pUpRadio->bSetParams){ if(verbose)pc.printf("\n\r setting radio params"); if(verbose)pc.printf("\n\r setting adr to %d ",pUpRadio->params.aDR); if (pUpRadio->params.aDR == 1) dot->setAdr(true); //test for adr problem else dot->setAdr(false); dot->setAdr((uint8_t)pUpRadio->params.aDR); // enable or disable Adaptive Data Rate if(verbose)pc.printf("\n\r setting subband to %d ",pUpRadio->params.sub_band); cfg_network(false,true,(uint8_t)pUpRadio->params.sub_band); if(verbose)pc.printf("\n\r setting public/private network to %d ",pUpRadio->params.public_network); //public_network = (bool)pUpRadio->params.public_network; dot->setPublicNetwork((bool)pUpRadio->params.public_network); if(verbose)pc.printf("\n\r setting antenna gain to %d ",pUpRadio->params.antennaGaindBi); dot->setAntennaGain(pUpRadio->params.antennaGaindBi); if(verbose)pc.printf("\n\r setting radio tx power to %d ",pUpRadio->params.txPower); dot->setTxPower(pUpRadio->params.txPower); if(verbose)pc.printf("\n\r setting tx datarate to %d ",pUpRadio->params.dataRate); dot->setTxDataRate(pUpRadio->params.dataRate); if(verbose)pc.printf("\n\r setting tx inverted to %d ",(bool)pUpRadio->params.txInverted); dot->setTxInverted((bool)pUpRadio->params.txInverted); if(verbose)pc.printf("\n\r setting rx inverted to %d ",(bool)pUpRadio->params.rxInverted); dot->setRxInverted((bool)pUpRadio->params.rxInverted); if(verbose)pc.printf("\n\r setting rx delay to %d ",pUpRadio->params.rxDelay); dot->setRxDelay(pUpRadio->params.rxDelay); if(verbose)pc.printf("\n\r setting join delay to %d ",pUpRadio->params.join_delay); dot->setJoinDelay(pUpRadio->params.join_delay); if(verbose)pc.printf("\n\r saving configuration"); if (!dot->saveConfig())logError("failed to save configuration"); display_config(); } if(verbose)pc.printf("\n\r reading radio params"); pDwnRadio->params.public_network = public_network; pDwnRadio->params.sub_band = dot->getFrequencySubBand(); pDwnRadio->params.join_delay = dot->getJoinDelay(); pDwnRadio->params.txInverted = dot->getTxInverted(); pDwnRadio->params.rxInverted = dot->getRxInverted(); pDwnRadio->params.rxDelay = dot->getRxDelay(); pDwnRadio->params.maxDataLen = dot->getMaxPacketLength(); pDwnRadio->params.maxTxPowerdBm = dot->getMaxTxPower(); pDwnRadio->params.minTxPowerdBm = dot->getMinTxPower(); pDwnRadio->params.aDR = dot->getAdr(); pDwnRadio->params.antennaGaindBi = dot->getAntennaGain(); pDwnRadio->params.txPower = dot->getTxPower(); //programmed tx power (non-adr) pDwnRadio->params.dataRate = dot->getTxDataRate(); //programmed data rate (non-adr) pDwnRadio->params.dataRateCurrent = dot->getSettings()->Session.TxDatarate; //presently used data rate (adr can change this);see Lora.h pDwnRadio->params.txPowerCurrent = dot->getSettings()->Session.TxPower;//presently used tx power (adr can change this);see Lora.h pDwnRadio->params.rx1DelayCurrent = dot->getSettings()->Session.RxDelay;//presently used rx1_delay;see Lora.h break; case XDOT_CMD_GET_EUI: //0307: modified to include radio parameter settings if(verbose)pc.printf("\n\r proc cmd: get EUI"); pkt_eui *peui = (pkt_eui*)&buf_xmt[0]; peui->ack = I2C_ACK_PROC; peui->cmd = XDOT_CMD_GET_EUI; upstream_packet.clear(); upstream_packet = dot->getDeviceId(); peui->dataLen = upstream_packet.size(); for (i=0; i< peui->dataLen;i++) peui->euiData[i] = upstream_packet[i]; for (i=0; i< 4;i++) peui->apiLvlData[i] = api_level[i]; for (i=0; i< 4;i++) peui->verLvlData[i] = ver_level[i]; peui->dataLen = sizeof(pkt_eui)-3; //size of struc minus first 3 bytes if(verbose)pc.printf("\n\r eui data length: %d",peui->dataLen); break; case XDOT_CMD_NVM: if(verbose)pc.printf("\n\r proc cmd: NVM OTAA"); pkt_setnvmup *pUpNvm = (pkt_setnvmup*)&buf_rcv[0]; pkt_setnvmdwn *pDwnNvm= (pkt_setnvmdwn*)&buf_xmt[0]; pDwnNvm->ack = I2C_ACK_PROC; pDwnNvm->cmd = XDOT_CMD_NVM; pDwnNvm->dataLen = sizeof(nvm)-2; if (pUpNvm->nvm_option == XDOT_NVM_SET) nvmWrite(&pUpNvm->nvmData); if (pUpNvm->nvm_option == XDOT_NVM_RESTORE) nvmRestore(&pUpNvm->nvmData); pDwnNvm->bChkSumOK = 0; if (nvmRead(&pDwnNvm->nvmData)) pDwnNvm->bChkSumOK = 1; printNmvData(&pDwnNvm->nvmData); break; case XDOT_CMD_NVM_ABP: if(verbose)pc.printf("\n\r proc cmd: NVM ABP"); pkt_setnvmABPup *pUpNvmABP = (pkt_setnvmABPup*)&buf_rcv[0]; pkt_setnvmABPdwn *pDwnNvmABP= (pkt_setnvmABPdwn*)&buf_xmt[0]; pDwnNvmABP->ack = I2C_ACK_PROC; pDwnNvmABP->cmd = XDOT_CMD_NVM_ABP; pDwnNvmABP->dataLen = sizeof(nvmABP)-2; if (pUpNvmABP->nvm_option == XDOT_NVM_SET) nvmWriteABP(&pUpNvmABP->nvmData); pDwnNvmABP->bChkSumOK = 0; if (nvmReadABP(&pDwnNvmABP->nvmData)) pDwnNvmABP->bChkSumOK = 1; printNvmABPData(&pDwnNvmABP->nvmData); break; case XDOT_CMD_SET_RADIO_CLASS: //multicast_change_class A or C (change only after a join!) if(verbose)pc.printf("\n\r proc cmd: change radio class\r\n"); pkt_setClassUp *pUpSetClass = (pkt_setClassUp*)&buf_rcv[0]; pkt_setClassDwn *pDwnSetClass = (pkt_setClassDwn*)&buf_xmt[0]; pDwnSetClass->ack = I2C_ACK_PROC; pDwnSetClass->cmd = XDOT_CMD_SET_RADIO_CLASS; pDwnSetClass->dataLen = sizeof(class_switch)-2; bool bOk = multicast_change_class(&pUpSetClass->classData); if (bOk && pUpSetClass->classData.bClassC) bClassA = false; pDwnSetClass->bSwitched = bOk; break; case XDOT_CMD_SET_NTWKSESS: //read or write network seesion to xdot flash bool bWriteSession = (bool)buf_rcv[1]; if (bWriteSession){ if(verbose)pc.printf("\n\r proc cmd writing network sesion to flash"); dot->saveNetworkSession(); } else{ if(verbose)pc.printf("\n\r reading network session from flash"); dot->restoreNetworkSession(); } pkt_ntwrk *pktwrk = (pkt_ntwrk*)&buf_xmt[0]; pktwrk->ack = I2C_ACK_PROC; pktwrk->cmd = XDOT_CMD_SET_NTWKSESS; pktwrk->bSetNetwrk = (uint8_t)bWriteSession; break; case XDOT_CMD_SET_KEY_X: if(verbose)pc.printf("\n\r proc cmd: this command not used\r\n"); wait_ms(I2C_MIN_WAIT_DELAY); buf_xmt[0] = I2C_ACK_PROC; buf_xmt[1] = XDOT_CMD_SET_KEY_X; break; case XDOT_CMD_GATEWAY_PING: if(verbose)pc.printf("\n\r proc cmd: xmit gateway ping\r\n"); pkt_ping *pPing = (pkt_ping*)&buf_xmt[0]; pPing->ack = I2C_ACK_PROC; pPing->cmd = XDOT_CMD_GATEWAY_PING; pPing->dataLen = 3; //only 3 bytes returned if(verbose)pc.printf("\r\n----------- SENDING GATEWAY PING \r\n"); mDot::ping_response ping_res; ping_res = dot->ping(); pPing->status = (int8_t)ping_res.status; pPing->rssi = (int8_t)ping_res.rssi; pPing->snr = (int8_t)ping_res.snr; if (ping_res.status == 0) if(verbose)pc.printf("\r\n----------- GATEWAY PING SUCCEEDED \r\n"); else if(verbose)pc.printf("\r\n----------- GATEWAY PING FAIL \r\n"); break; default: if(verbose)pc.printf("\n\r proc cmd not recognized:%x",buf_rcv[0]); wait_ms(I2C_MIN_WAIT_DELAY); buf_xmt[0] = I2C_ACK_PROC; buf_xmt[1] = XDOT_CMD_UNDEFINED; } //switch buf_rcv[0] //gpio1 =1; //test if (bPulseLoraWake) i2c_pulse_wake(); //pulse wake-up lo->hi->lo to signal proc that xdot ready to send ack } //switch i2c_proc_comm } //while } //main