MTDOT-EVB link check code for site survey
Dependencies: DOGS102 GpsParser MTS-Serial NCP5623B libmDot mbed-rtos mbed
Revision 0:dba397ff987f, committed 2015-10-22
- Comitter:
- falingtrea
- Date:
- Thu Oct 22 19:45:01 2015 +0000
- Child:
- 1:4e3ee9c860e3
- Commit message:
- Copied from MDOT-EVB-LinkCheck. Added mutex around certain mDot radio commands. Moved ping check code to callable function. Added sweep mode, re-wrote join code, and modified button operation. Fixed error in Downlink QOS SNR display.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DOGS102.lib Thu Oct 22 19:45:01 2015 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/teams/Multi-Hackers/code/DOGS102/#3b02b7fb79c9
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GpsParser.lib Thu Oct 22 19:45:01 2015 +0000 @@ -0,0 +1,1 @@ +https://developer.mbed.org/teams/Multi-Hackers/code/GpsParser/#662aa99c5266
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MTS-Serial.lib Thu Oct 22 19:45:01 2015 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/teams/MultiTech/code/MTS-Serial/#4afbbafcd6b3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NCP5623B.lib Thu Oct 22 19:45:01 2015 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/teams/Multi-Hackers/code/NCP5623B/#b28a2dfe05fd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmDot.lib Thu Oct 22 19:45:01 2015 +0000 @@ -0,0 +1,1 @@ +https://developer.mbed.org/teams/MultiTech/code/libmDot/#0b4eb17d07ae
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Thu Oct 22 19:45:01 2015 +0000
@@ -0,0 +1,775 @@
+/**
+ * @file main.cpp
+ * @brief Main application for mDot-EVB Automated Link Check demo
+ * @author Tim Barr MultiTech Systems Inc.
+ * @version 1.02
+ * @see
+ *
+ * Copyright (c) 2015
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * 1.00 TAB 10/22/15 Copied from MDOT-EVB-LinkCheck version 1.02.
+ * Added mutex around certain mDot radio commands.
+ * Moved ping check code to callable function. Added sweep
+ * mode, re-wrote join code, and modified button operation
+ * Fixed error in Downlink QOS SNR display.
+ */
+
+#include "mbed.h"
+#include "NCP5623B.h"
+#include "DOGS102.h"
+#include "font_6x8.h"
+#include "MultiTech_Logo.h"
+#include "mDot.h"
+#include "rtos.h"
+#include "GPSPARSER.h"
+#include "MTSSerial.h"
+#include <string>
+#include <vector>
+#include <ctime>
+
+enum LED1_COLOR {
+ RED = 0,
+ GREEN = 1
+};
+
+/*
+ * union for converting from 32-bit to 4 8-bit values
+ */
+union convert32 {
+ int32_t f_s; // convert from signed 32 bit int
+ uint32_t f_u; // convert from unsigned 32 bit int
+ uint8_t t_u[4]; // convert to 8 bit unsigned array
+};
+
+/*
+ * union for converting from 16- bit to 2 8-bit values
+ */
+union convert16 {
+ int16_t f_s; // convert from signed 16 bit int
+ uint16_t f_u; // convert from unsigned 16 bit int
+ uint8_t t_u[2]; // convert to 8 bit unsigned array
+};
+
+//DigitalIn mDot02(PA_2); // GPIO/UART_TX
+//DigitalOut mDot03(PA_3); // GPIO/UART_RX
+//DigitalIn mDot04(PA_6); // GPIO/SPI_MISO
+//DigitalIn mDot06(PA_8); // GPIO/I2C_SCL
+//DigitalIn mDot07(PC_9); // GPIO/I2C_SDA
+
+InterruptIn mDot08(PA_12); // GPIO/USB PB S1 on EVB
+InterruptIn mDot09(PA_11); // GPIO/USB PB S2 on EVB
+
+//DigitalIn mDot11(PA_7); // GPIO/SPI_MOSI
+
+InterruptIn mDot12(PA_0); // GPIO/UART_CTS PRESSURE_INT2 on EVB
+DigitalOut mDot13(PC_13,1); // GPIO LCD_C/D
+InterruptIn mDot15(PC_1); // GPIO LIGHT_PROX_INT on EVB
+InterruptIn mDot16(PA_1); // GPIO/UART_RTS ACCEL_INT2 on EVB
+DigitalOut mDot17(PA_4,1); // GPIO/SPI_NCS LCD_CS on EVB
+
+//DigitalIn mDot18(PA_5); // GPIO/SPI_SCK
+
+//DigitalInOut mDot19(PB_0,PIN_INPUT,PullNone,0); // GPIO PushPull LED Low=Red High=Green set MODE=INPUT to turn off
+AnalogIn mDot20(PB_1); // GPIO Current Sense Analog in on EVB
+
+Serial debugUART(PA_9, PA_10); // mDot debug UART
+
+MTSSerial mDotUART(PA_2,PA_3); // mDot external UART mDot02 and mDot03
+
+I2C mDoti2c(PC_9,PA_8); // mDot External I2C mDot6 and mDot7
+
+SPI mDotspi(PA_7,PA_6,PA_5); // mDot external SPI mDot11, mDot4, and mDot18
+
+/* **** replace these values with the proper public or private network settings ****
+ * config_network_nameand config_network_pass are for private networks.
+ */
+static std::string config_network_name = "TAB-CubeNet";
+static std::string config_network_pass = "1nt3gral";
+//static std::string config_network_name = "Arclight";
+//static std::string config_network_pass = "default1";
+static uint8_t config_frequency_sub_band = 5;
+
+//static std::string config_network_name = "GregCDT8";
+//static std::string config_network_pass = "myAEP8chars";
+//static uint8_t config_frequency_sub_band = 1;
+
+/* config_app_id and config_app_key are for public networks.
+static uint8_t app_id[8] = {0x00,0x01,0x02,0x03,0x0A,0x0B,0x0C,0x0D};
+std::vector<uint8_t> config_app_id;
+static uint8_t app_key[16] = {0x00,0x01,0x02,0x03,0x0A,0x0B,0x0C,0x0D};
+std::vector<uint8_t> config_app_key;
+*/
+
+uint8_t result;
+uint8_t data;
+uint8_t sf_val = mDot::SF_7;
+uint8_t pwr_val = 11; // dBm
+uint8_t swp_pwr;
+uint8_t swp_sf;
+
+const uint8_t sweep_table [2][4] = {
+ { 11, 14, 18, 20},
+ {mDot::SF_7, mDot::SF_8, mDot::SF_9, mDot::SF_10}
+ };
+
+// max size of text string for 6x8 font. Set to 12 if using 8x8 font
+char txtstr[17];
+
+int32_t mdot_ret;
+int32_t join_delay;
+
+osThreadId mainThreadID;
+
+// flags for push button debounce code
+bool pb1_low = false;
+bool pb2_low = false;
+bool toggle_text = false;
+bool main_single = false;
+bool main_sweep = false;
+
+NCP5623B* evbBackLight;
+DOGS102* evbLCD;
+
+mDot* mdot_radio;
+Mutex mdot_mutex;
+
+GPSPARSER* mdot_gps;
+
+convert32 convertL;
+convert16 convertS;
+
+void pb1ISR(void);
+void pb2ISR(void);
+void pb1_debounce(void const *args);
+void pb2_debounce(void const *args);
+
+void log_error(mDot* dot, const char* msg, int32_t retval);
+
+uint8_t ping_check(uint8_t set_pwr, uint8_t set_sf, uint8_t pings_per_check = 1);
+
+int main()
+{
+ std::vector<uint8_t> mdot_EUI;
+ uint16_t i = 0;
+
+// Number of ping attempts per Radio setting set here
+ uint8_t number_of_pings = 5;
+
+ debugUART.baud(115200);
+
+ printf ("Start program \r\n");
+
+ Thread thread_1(pb1_debounce);
+ Thread thread_2(pb2_debounce);
+
+ printf("Thread init done\r\n");
+
+ mainThreadID = osThreadGetId();
+
+ printf("Device init start\r\n");
+
+ evbBackLight = new NCP5623B(mDoti2c); // setup backlight and LED 2 driver chip
+ evbLCD = new DOGS102(mDotspi, mDot17, mDot13); // setup LCD
+
+ printf ("Devices init done\r\n");
+ /*
+ * Setup SW1 as Data rate and power out select
+ */
+ mDot08.disable_irq();
+ mDot08.fall(&pb1ISR);
+
+ /*
+ * need to call this function after rise or fall because rise/fall sets
+ * mode to PullNone
+ */
+ mDot08.mode(PullUp);
+
+ mDot08.enable_irq();
+
+ /*
+ * Setup SW2 as send PING
+ */
+ mDot09.disable_irq();
+ mDot09.fall(&pb2ISR);
+
+ /*
+ * need to call this function after rise or fall because rise/fall sets
+ * mode to PullNone
+ */
+ mDot09.mode(PullUp);
+
+ mDot09.enable_irq();
+
+ /*
+ * Setting other InterruptIn pins with Pull Ups
+ */
+ mDot12.mode(PullUp);
+ mDot15.mode(PullUp);
+ mDot16.mode(PullUp);
+
+ printf("Switch IRQs set\r\n");
+
+ printf("font table address %p\r\n",&font_6x8);
+ printf("bitmap address %p\r\n",&MultiTech_Logo);
+
+// Setup and display logo on LCD
+ evbLCD->startUpdate();
+
+ evbLCD->writeBitmap(0,0,MultiTech_Logo);
+
+ sprintf(txtstr,"MTDOT-EVB");
+ evbLCD->writeText(24,3,font_6x8,txtstr,strlen(txtstr));
+ sprintf(txtstr,"Link Check Demo");
+ evbLCD->writeText(6,4,font_6x8,txtstr,strlen(txtstr));
+
+ evbLCD->endUpdate();
+
+ printf("\r\n setup mdot\r\n");
+
+ // get a mDot handle
+ mdot_radio = mDot::getInstance();
+
+ if (mdot_radio) {
+ // reset to default config so we know what state we're in
+ mdot_mutex.lock(); // lock mdot before setting configuration
+ mdot_radio->resetConfig();
+
+ // Setting up LED1 as activity LED
+ mdot_radio->setActivityLedPin(PB_0);
+ mdot_radio->setActivityLedEnable(true);
+
+ // Read node ID
+ mdot_EUI = mdot_radio->getDeviceId();
+ printf("mDot EUI = ");
+
+ for (i=0; i<mdot_EUI.size(); i++) {
+ printf("%02x ", mdot_EUI[i]);
+ }
+ printf("\r\n");
+
+// Setting up the mDot with network information.
+
+ /*
+ * This call sets up private or public mode on the MTDOT. Set the function to true if
+ * connecting to a public network
+ */
+ printf("setting Private Network Mode\r\n");
+ if ((mdot_ret = mdot_radio->setPublicNetwork(false)) != mDot::MDOT_OK) {
+ log_error(mdot_radio, "failed to set Public Network Mode", mdot_ret);
+ }
+
+ /*
+ * Frequency sub-band is valid for NAM only and for Private networks should be set to a value
+ * between 1-8 that matches the the LoRa gateway setting. Public networks use sub-band 0 only.
+ * This function can be commented out for EU networks
+ */
+ printf("setting frequency sub band\r\n");
+ if ((mdot_ret = mdot_radio->setFrequencySubBand(config_frequency_sub_band)) != mDot::MDOT_OK) {
+ log_error(mdot_radio, "failed to set frequency sub band", mdot_ret);
+ }
+
+ /*
+ * Setting TX power for radio. Max allowed is +14dBm for EU and +20 dBm for NAM. Default is +11 dBm
+ */
+ printf("setting TX Power Level to %2d dBm\r\n", pwr_val);
+ if ((mdot_ret = mdot_radio->setTxPower(pwr_val)) != mDot::MDOT_OK) {
+ log_error(mdot_radio, "failed to set TX power level", mdot_ret);
+ }
+
+ /*
+ * Setting TX data rate for radio. Max allowed is SF_12 for EU and SF10 dBm for NAM. Default is SF_10
+ */
+ printf("setting TX data rate to SF_7\r\n");
+ if ((mdot_ret = mdot_radio->setTxDataRate(sf_val)) != mDot::MDOT_OK) {
+ log_error(mdot_radio, "failed to set TX data rate", mdot_ret);
+ }
+
+ sprintf(txtstr,"DR=%2d Pwr=%2d",(12 - sf_val),pwr_val);
+ evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr));
+ printf("%s \r\n",txtstr);
+
+ /*
+ * Setting packet ACK to 1 try.
+ */
+ printf("setting Packet retry to 1\r\n");
+ if ((mdot_ret = mdot_radio->setAck(1)) != mDot::MDOT_OK) {
+ log_error(mdot_radio, "failed to set packet retry\r\n", mdot_ret);
+ }
+
+ /*
+ * setNetworkName is used for private networks.
+ * Use setNetworkID(AppID) for public networks
+ */
+
+// config_app_id.assign(app_id,app_id+7);
+
+ printf("setting network name\r\n");
+ if ((mdot_ret = mdot_radio->setNetworkName(config_network_name)) != mDot::MDOT_OK) {
+// if ((mdot_ret = mdot_radio->setNetworkID(config_app_id)) != mDot::MDOT_OK) {
+ log_error(mdot_radio, "failed to set network name", mdot_ret);
+ }
+
+ /*
+ * setNetworkPassphrase is used for private networks
+ * Use setNetworkKey for public networks
+ */
+
+// config_app_key.assign(app_key,app_key+15);
+
+ printf("setting network password\r\n");
+ if ((mdot_ret = mdot_radio->setNetworkPassphrase(config_network_pass)) != mDot::MDOT_OK) {
+// if ((mdot_ret = mdot_radio->setNetworkKey(config_app_key)) != mDot::MDOT_OK) {
+ log_error(mdot_radio, "failed to set network password", mdot_ret);
+ }
+
+ mdot_mutex.unlock(); // unlock mdot mutex before join attempt so SW1 can work
+
+ // attempt to join the network
+ printf("joining network\r\n");
+ do {
+ mdot_mutex.lock(); // lock mdot mutex before join attempt
+ mdot_ret = mdot_radio->joinNetwork();
+ mdot_mutex.unlock(); // unlock mdot mutex after join attempt so SW1 can work
+
+ if (mdot_ret != mDot::MDOT_OK) {
+ log_error(mdot_radio,"failed to join network:", mdot_ret);
+
+ if (toggle_text)
+ sprintf(txtstr," > Join Failed <");
+ else
+ sprintf(txtstr," < Join Failed >");
+
+ evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr));
+
+ if (mdot_radio->getFrequencyBand() == mDot::FB_868) {
+ join_delay = mdot_radio->getNextTxMs();
+ } else {
+ join_delay = 10;
+ }
+ printf("delay = %lu\r\n",join_delay);
+ osDelay(join_delay + 1);
+ toggle_text = !toggle_text;
+ }
+
+ /*
+ * Setting TX power and Data Rate for radio just in case user requested by SW2
+ */
+ mdot_mutex.lock(); // lock mdot mutex before setting change
+ mdot_radio->setTxPower(pwr_val);
+ mdot_radio->setTxDataRate(sf_val);
+ mdot_mutex.unlock(); // unlock mdot mutex after settings change so SW1 can work
+
+ } while (mdot_ret != mDot::MDOT_OK);
+
+ sprintf(txtstr,"*Network Joined*");
+ evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr));
+
+ } else {
+ sprintf(txtstr,"Radio Init Failed!");
+ evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr));
+ printf("%s\r\n",txtstr);
+ exit(1);
+ }
+
+ mdot_gps = new GPSPARSER(&mDotUART);
+
+ if (!mdot_gps->gpsDetected()){
+ sprintf(txtstr,"*No GPS Detected*");
+ evbLCD->writeText(0,6,font_6x8,txtstr,strlen(txtstr));
+ printf ("%s\r\n", txtstr);
+ }
+ else {
+ main_single = main_sweep = false;
+ do {
+ osSignalWait(0x10, 2000);
+ if (mdot_gps->getLockStatus()){
+ sprintf(txtstr,"!!GPS locked!!");
+ evbLCD->writeText(0,6,font_6x8,txtstr,strlen(txtstr));
+ printf("%s \r\n",txtstr);
+ }
+ else {
+ if (toggle_text)
+ sprintf(txtstr," > no GPS lock <");
+ else
+ sprintf(txtstr," < no GPS lock >");
+
+ evbLCD->writeText(0,6,font_6x8,txtstr,strlen(txtstr));
+ printf("%s \r\n",txtstr);
+ toggle_text = !toggle_text;
+ }
+ } while ( !(mdot_gps->getLockStatus()) && (!main_single && !main_sweep));
+ }
+ osDelay(200);
+ evbBackLight->setPWM(NCP5623B::LED_3,16); // enable LED2 on EVB and set to 50% PWM
+
+ // sets LED2 to 50% max current
+ evbBackLight->setLEDCurrent(16);
+
+ osDelay (500); // allows other threads to process
+ printf("shutdown LED:\r\n");
+ evbBackLight->shutdown();
+ osDelay(500);
+ /*
+ * Main data acquisition loop
+ */
+ i = 0;
+
+ do {
+
+ // Main program waits until SW2 is pressed.
+ main_single = main_sweep = false;
+
+ sprintf(txtstr,"Ready for Trigger");
+ evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr));
+ printf ("%s\r\n", txtstr);
+
+ osSignalWait(0x10, osWaitForever);
+
+ if (main_single) {
+ evbLCD->clearBuffer();
+ sprintf(txtstr,"**Single Ping**");
+ evbLCD->writeText(0,4,font_6x8,txtstr,strlen(txtstr));
+
+ result = ping_check(pwr_val, sf_val);
+
+ if (result != 0)
+ printf("Ping check completed\r\n");
+ else
+ printf("Ping check failed \r\n");
+ }
+ else if (main_sweep) {
+
+ evbLCD->clearBuffer();
+ sprintf(txtstr,"**Ping Sweep**");
+ evbLCD->writeText(0,4,font_6x8,txtstr,strlen(txtstr));
+
+ printf("start sweep and shutdown LED:\r\n");
+ evbBackLight->shutdown();
+
+ for (swp_pwr = 0; swp_pwr < 4; swp_pwr++)
+ {
+ for (swp_sf = 0; swp_sf < 4; swp_sf++)
+ {
+ result = ping_check(sweep_table[0][swp_pwr], sweep_table[1][swp_sf], number_of_pings);
+
+ if (result != 0)
+ printf("Ping check completed %d attempts\r\n", result);
+ else
+ printf("Ping check failed all attempts\r\n");
+
+ osDelay(1000);
+ }
+ }
+ }
+ else {
+ printf("Got here because of code error.\r\n");
+ osDelay(1000);
+ }
+
+ } while(i < 1000);
+
+ printf("End of Test\r\n");
+
+ evbLCD->clearBuffer();
+ sprintf(txtstr,"Exiting Program");
+ evbLCD->writeText(0,4,font_6x8,txtstr,strlen(txtstr));
+}
+
+/*
+ * Sets pb1_low flag. Flag is cleared in pb1_debounce thread
+ */
+void pb1ISR(void)
+{
+ if (!pb1_low)
+ pb1_low = true;
+}
+
+/*
+ * Debounces pb1 PB1 changes spreading factor and output power
+ * Cycles through SF_7-SF_10 for 4 power levels
+ */
+void pb1_debounce(void const *args)
+{
+ static uint8_t count = 0;
+ static uint8_t test_now = 0;
+
+ while (true) {
+
+ if (pb1_low && (mDot08 == 0))
+ count++;
+ else {
+ count = 0;
+ pb1_low = false;
+ }
+
+ if (count == 5) {
+ test_now++;
+
+ if (test_now > 15) // resets test_now
+ test_now = 0;
+
+ // selects power output level using upper bits for select
+ switch(test_now >> 2){
+ case 0:
+ pwr_val = 11;
+ break;
+ case 1:
+ pwr_val = 14;
+ break;
+ case 2:
+ pwr_val = 18;
+ break;
+ case 3:
+ pwr_val = 20;
+ }
+
+ // sets data rate based on lower bits
+ sf_val = mDot::SF_7 - (test_now & 0x03);
+
+ sprintf(txtstr,"DR=%2d Pwr=%2d ",(12 - sf_val),pwr_val);
+ evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr));
+ printf("%s \r\n",txtstr);
+ }
+
+ Thread::wait(5);
+ }
+}
+
+/*
+ * Sets pb2_low flag. Flag is cleared in pb2_debounce thread
+ */
+void pb2ISR(void)
+{
+ if (!pb2_low)
+ pb2_low = true;
+}
+
+/*
+ * Debounces pb2 PB2 forces main program out of thread wait mode
+ */
+void pb2_debounce(void const *args)
+{
+
+ static uint8_t count = 0;
+
+ while (true) {
+
+ if (pb2_low && (mDot09 == 0)){
+ count++;
+ if (count == 100){
+ // sets LED2 to 50% max current
+ evbBackLight->setPWM(NCP5623B::LED_3,16); // enable LED2 on EVB and set to 50% PWM
+ evbBackLight->setLEDCurrent(16);
+ }
+ }
+ else {
+ if ((count > 5) && (count <= 100)) {
+ main_single = true;
+ osSignalSet(mainThreadID, 0x10);
+ } else if (count > 100) {
+ main_sweep = true;
+ osSignalSet(mainThreadID, 0x10);
+ }
+
+ count = 0;
+ pb2_low = false;
+ }
+
+ Thread::wait(5);
+ }
+ }
+
+/*
+ * Function that print clear text verion of mDot errors
+ */
+void log_error(mDot* dot, const char* msg, int32_t retval)
+{
+ printf("%s - %ld:%s, %s\r\n", msg, retval, mDot::getReturnCodeString(retval).c_str(), dot->getLastError().c_str());
+}
+
+// return = number of ping checks that passed
+uint8_t ping_check(uint8_t set_pwr, uint8_t set_sf, uint8_t pings_per_check)
+{
+
+ uint8_t result = 0;
+ uint8_t ping_cnt;
+ mDot::ping_response ping_data;
+ mDot::rssi_stats rssi_data;
+ mDot::snr_stats snr_data;
+ struct tm gps_timestamp;
+ GPSPARSER::longitude evb_longitude;
+ GPSPARSER::latitude evb_latitude;
+ GPSPARSER::satellite_prn gps_sat_prn;
+ uint8_t gps_fix_quality;
+ int16_t evb_altitude;
+ uint8_t gps_num_satellites;
+ uint8_t gps_fix_status;
+ std::vector<uint8_t> mdot_data;
+
+ mdot_mutex.lock(); // lock mdot mutex before changing radio parameters
+ if ((mdot_ret = mdot_radio->setTxPower(set_pwr)) != mDot::MDOT_OK) {
+ log_error(mdot_radio, "failed to set TX power level", mdot_ret);
+ }
+ if ((mdot_ret = mdot_radio->setTxDataRate(set_sf)) != mDot::MDOT_OK) {
+ log_error(mdot_radio, "failed to set DataRate value", mdot_ret);
+ }
+ mdot_mutex.unlock(); // unlock mdot mutex after changing radio parameters
+
+ for (ping_cnt = 0; ping_cnt < pings_per_check; ping_cnt++) {
+ evbLCD->startUpdate();
+ evbLCD->clearBuffer();
+
+ mdot_mutex.lock(); // lock mdot mutex before ping
+ ping_data = mdot_radio->ping();
+ mdot_mutex.unlock(); // unlock mdot mutex after ping
+
+ if (ping_data.status == mDot::MDOT_OK) {
+ rssi_data = mdot_radio->getRssiStats();
+ snr_data = mdot_radio->getSnrStats();
+ gps_fix_status = mdot_gps->getFixStatus();
+ gps_fix_quality = mdot_gps->getFixQuality();
+ gps_num_satellites = mdot_gps->getNumSatellites();
+
+ printf ("\r\n GPS Fix Status= %d num of sats = %d\r\n", gps_fix_status, gps_num_satellites);
+
+ sprintf(txtstr,"PGOOD DR=%2d P=%2d",(12 - set_sf),set_pwr);
+ evbLCD->writeText(0,0,font_6x8,txtstr,strlen(txtstr));
+ printf("%s \r\n",txtstr);
+
+ sprintf(txtstr,"UP %3d dBm %2d.%1d",ping_data.rssi, ping_data.snr/10, abs(ping_data.snr)%10);
+ evbLCD->writeText(0,1,font_6x8,txtstr,strlen(txtstr));
+ printf("Link Quality %s \r\n",txtstr);
+
+ sprintf(txtstr,"DWN %3d dBm %2d.%02d",rssi_data.last, snr_data.last/4, abs(snr_data.last)%4*25);
+ evbLCD->writeText(0,2,font_6x8,txtstr,strlen(txtstr));
+ printf("Link Quality %s \r\n",txtstr);
+
+ mdot_data.clear();
+ mdot_data.push_back(0x1D); // key for start of data structure
+ mdot_data.push_back(0x1A); // key for uplink QOS + RF Pwr
+ convertS.f_s = ping_data.rssi;
+ mdot_data.push_back(convertS.t_u[1]);
+ mdot_data.push_back(convertS.t_u[0]);
+ mdot_data.push_back((ping_data.snr/10) & 0xFF);
+ mdot_data.push_back(set_pwr);
+
+ mdot_data.push_back(0x1B); // key for downlink QOS
+ convertS.f_s=rssi_data.last;
+ mdot_data.push_back(convertS.t_u[1]);
+ mdot_data.push_back(convertS.t_u[0]);
+ mdot_data.push_back(snr_data.last);
+
+ // collect GPS data if GPS device detected
+ if (mdot_gps->gpsDetected() && (set_sf != mDot::SF_10)){
+
+ mdot_data.push_back(0x19); // key for GPS Lock Status
+ data = ( gps_num_satellites << 4 ) | ( gps_fix_status & 0x0F );
+ mdot_data.push_back(data);
+
+ if (mdot_gps->getLockStatus()){ // if gps has a lock
+ evb_longitude = mdot_gps->getLongitude();
+ evb_latitude = mdot_gps->getLatitude();
+ evb_altitude = mdot_gps->getAltitude();
+ gps_timestamp = mdot_gps->getTimestamp();
+
+ sprintf(txtstr,"%3d %2d %2d.%03d",abs(evb_longitude.degrees),evb_longitude.minutes,(evb_longitude.seconds*6)/1000,(evb_longitude.seconds*6)%1000);
+
+ if (evb_longitude.degrees < 0)
+ strncat(txtstr," W",2);
+ else
+ strncat(txtstr," E",2);
+
+ evbLCD->writeText(0,3,font_6x8,txtstr,strlen(txtstr));
+ printf("Longitude: %s \r\n",txtstr);
+
+ sprintf(txtstr,"%3d %2d %2d.%03d",abs(evb_latitude.degrees),evb_latitude.minutes,(evb_latitude.seconds*6)/1000,(evb_latitude.seconds*6)%1000);
+
+ if (evb_latitude.degrees < 0)
+ strncat(txtstr," S",2);
+ else
+ strncat(txtstr," N",2);
+
+ evbLCD->writeText(0,4,font_6x8,txtstr,strlen(txtstr));
+ printf("Latitude: %s \r\n",txtstr);
+
+ sprintf(txtstr,"Time %02d:%02d:%02d ",gps_timestamp.tm_hour,gps_timestamp.tm_min,gps_timestamp.tm_sec);
+ evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr));
+ printf("%s \r\n",txtstr);
+
+ sprintf(txtstr,"Date %02d/%02d/%04d",gps_timestamp.tm_mon + 1,gps_timestamp.tm_mday,gps_timestamp.tm_year +1900);
+ evbLCD->writeText(0,6,font_6x8,txtstr,strlen(txtstr));
+ printf("%s \r\n\r\n",txtstr);
+
+ // Send GPS data if GSP device locked
+ mdot_data.push_back(0x15); // key for GPS Latitude
+ mdot_data.push_back(evb_latitude.degrees);
+ mdot_data.push_back(evb_latitude.minutes);
+ convertS.f_s = evb_latitude.seconds;
+ mdot_data.push_back(convertS.t_u[1]);
+ mdot_data.push_back(convertS.t_u[0]);
+
+ mdot_data.push_back(0x16); // key for GPS Longitude
+ convertS.f_s = evb_longitude.degrees;
+ mdot_data.push_back(convertS.t_u[1]);
+ mdot_data.push_back(convertS.t_u[0]);
+
+ mdot_data.push_back(evb_longitude.minutes);
+ convertS.f_s = evb_longitude.seconds;
+ mdot_data.push_back(convertS.t_u[1]);
+ mdot_data.push_back(convertS.t_u[0]);
+ }
+ else {
+ sprintf(txtstr,"no GPS lock");
+ evbLCD->writeText(0,4,font_6x8,txtstr,strlen(txtstr));
+ printf("%s \r\n",txtstr);
+ }
+ }
+ // key for end of data structure
+ mdot_data.push_back(0x1D);
+
+ // if SF_10 this sends 11 bytes of data, otherwise sends full data packet
+ mdot_mutex.lock(); // lock mdot mutex before packet send
+ mdot_ret = mdot_radio->send(mdot_data);
+ mdot_mutex.unlock(); // unlock mdot mutex after packet send
+
+ if (mdot_ret != mDot::MDOT_OK) {
+ sprintf(txtstr,"mDot Send failed");
+ evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr));
+ log_error(mdot_radio, txtstr, mdot_ret);
+ }
+ else {
+ sprintf(txtstr,"mDot Send success");
+ evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr));
+ printf("successfully sent data to gateway\r\n");
+ result++;
+ }
+ }
+ else {
+ sprintf(txtstr,"Ping Check Failed");
+ evbLCD->writeText(0,2,font_6x8,txtstr,strlen(txtstr));
+ printf("%s \r\n",txtstr);
+ sprintf(txtstr,"DR=%2d P=%2d",(12 - set_sf),set_pwr);
+ evbLCD->writeText(0,3,font_6x8,txtstr,strlen(txtstr));
+ printf("%s \r\n",txtstr);
+ strncpy(txtstr,mDot::getReturnCodeString(ping_data.status).c_str(),17);
+ evbLCD->writeText(0,4,font_6x8,txtstr,strlen(txtstr));
+ printf("%s \r\n",txtstr);
+ }
+
+ evbLCD->endUpdate();
+ osDelay(1000);
+ }
+ return result;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Thu Oct 22 19:45:01 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-rtos/#21b438192b0f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-src.lib Thu Oct 22 19:45:01 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-src/#9c82b0f79f3d