Demonstration of Class-A LoRaWAN device using NAMote-72

Dependencies:   LoRaWAN-lib mbed lib_mpl3115a2 lib_mma8451q lib_gps SX1272Lib

Dependents:   LoRaWAN-NAMote72-BVS-confirmed-tester-0-7v1_copy

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LoRaApp.cpp Source File

LoRaApp.cpp

00001 /*
00002  / _____)             _              | |
00003 ( (____  _____ ____ _| |_ _____  ____| |__
00004  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
00005  _____) ) ____| | | || |_| ____( (___| | | |
00006 (______/|_____)_|_|_| \__)_____)\____)_| |_|
00007     (C)2015 Semtech
00008 
00009 Description: User-defined applications such as GPS, Temp, Accelerometer, LED indications etc.
00010             Event based actions such as LED blink on Tx, LED toggle on downlink etc
00011 
00012 License: Revised BSD License, see LICENSE.TXT file include in the project
00013 
00014 Maintainer: Uttam Bhat
00015 */
00016 
00017 #include "LoRaApp.h"
00018 
00019 bool VerticalStatus = false;
00020 
00021 /*!
00022  * Red LED timer event
00023  */
00024 TimerLed RedLedTimer( Red );
00025 
00026 /*!
00027  * Yellow LED timer event
00028  */
00029 TimerLed YellowLedTimer( Yellow );
00030 
00031 /*!
00032  * Green LED timer event
00033  */
00034 TimerLed GreenLedTimer( Green );
00035 
00036 Application::Application( uint8_t * memptr )
00037 {
00038     BuffAddr = memptr;
00039     memset( BuffAddr, 0, LORAWAN_APP_DATA_MAX_SIZE );
00040     BuffPtr = 0;
00041 }
00042 
00043 Application::~Application( )
00044 {
00045 }
00046 
00047 void Application::ApplicationAppendData( uint8_t *pData, uint8_t len )
00048 {
00049     memcpy( BuffAddr + BuffPtr, pData, len );
00050     BuffPtr += len;
00051 }
00052 
00053 void Application::ApplicationPtrPos( uint8_t ptrPos )
00054 {
00055     BuffPtr = ptrPos;
00056 }
00057 
00058 void Application::ApplicationCall( eAppType App )
00059 {
00060     switch( App )
00061     {
00062         // Appends 8 Bytes (3 bytes longitude, 3 bytes latitude, 2 bytes altitude) to TX buffer
00063         case AppGps:
00064         {
00065             Gps.service( );
00066 
00067             uint16_t altitudeGps = atoi( Gps.NmeaGpsData.NmeaAltitude );
00068 
00069             if( ( BuffPtr + 8 ) <= LORAWAN_APP_DATA_SIZE )
00070             {
00071                 BuffAddr[BuffPtr++] = ( Gps.LatitudeBinary >> 16 ) & 0xFF;
00072                 BuffAddr[BuffPtr++] = ( Gps.LatitudeBinary >> 8 ) & 0xFF;
00073                 BuffAddr[BuffPtr++] = Gps.LatitudeBinary & 0xFF;
00074                 BuffAddr[BuffPtr++] = ( Gps.LongitudeBinary >> 16 ) & 0xFF;
00075                 BuffAddr[BuffPtr++] = ( Gps.LongitudeBinary >> 8 ) & 0xFF;
00076                 BuffAddr[BuffPtr++] = Gps.LongitudeBinary & 0xFF;           
00077                 BuffAddr[BuffPtr++] = ( altitudeGps >> 8 ) & 0xFF;
00078                 BuffAddr[BuffPtr++] = altitudeGps & 0xFF;
00079             }
00080             break;
00081         }
00082 
00083         // Appends 1 Byte to TX buffer
00084         case AppTemp:
00085         {
00086             Mpl3115a2.ReadTemperature( );
00087             if( ( BuffPtr + 1 ) <= LORAWAN_APP_DATA_SIZE )
00088             {
00089                 BuffAddr[BuffPtr++] = ( int32_t )Mpl3115a2.Temperature;     // Signed degrees Celcius in half degree units. So, +/-63 °C
00090             }
00091             break;
00092         }
00093 
00094         // Appends 1 Byte to TX buffer
00095         case AppBat:
00096         {  
00097             if( ( BuffPtr + 1 ) <= LORAWAN_APP_DATA_SIZE )
00098             {
00099                 BuffAddr[BuffPtr++] = BoardGetBatteryLevel( );              // Per LoRaWAN spec; 0 = Charging; 1...254 = level, 255 = N/A
00100             }
00101             break;
00102         }
00103 
00104         // Appends incremental values of 1 Byte each to TX buffer until Full
00105         case AppRamp:
00106         {
00107             int32_t i, j;
00108 
00109             // Populate Tx Buffer with increasing byte values starting from 0x00, 0x01, 0x02 ...
00110             for( i = BuffPtr, j = 0; i < LORAWAN_APP_DATA_SIZE; i++ )
00111             {
00112                 BuffAddr[i] = j++;
00113             }
00114             BuffPtr = LORAWAN_APP_DATA_SIZE;
00115             break;
00116         }
00117 
00118         // Appends 2 Bytes to TX buffer
00119         case AppAccl:
00120         {   
00121             uint8_t statusReg; 
00122 
00123             // Read the PS_STATUS register
00124             statusReg = Mma8451q.read_single( MMA8451_PL_STATUS );
00125 
00126             /* Display Orientation of NAMote on Serial Port */
00127             //SerialAcclMetrDisplay( statusReg );
00128 
00129             // If Orientation of the Mote changed then let Green LED ON
00130             if( ( statusReg & 0x80 ) != 0 )
00131             {
00132                 AppLed = 1;
00133                 CtrlLED( Green, LED_ON );
00134             }
00135 
00136             // Read and populate device orientation in Tx Buffer
00137             if( ( BuffPtr + 2 ) <= LORAWAN_APP_DATA_SIZE )
00138             {
00139                 if( statusReg & 0x40 )
00140                 {
00141                     if( statusReg & 0x01 )
00142                     {
00143                         BuffAddr[BuffPtr++] = 0x66; // horizontal + faceup
00144                     }
00145                     else
00146                     {
00147                         BuffAddr[BuffPtr++] = 0x99; // horizontal + facedown
00148                     }
00149 
00150                     BuffAddr[BuffPtr++] = 0; // vertical = false
00151                 }
00152                 else
00153                 {
00154                     BuffAddr[BuffPtr++] = 0; // horizontal = false
00155                     BuffAddr[BuffPtr++] = 0x11; // vertical = true
00156                 }
00157             }
00158 
00159             break;
00160         }
00161 
00162         case AppAcclSenet:
00163         {
00164             uint8_t statusReg; 
00165 
00166             // Read the PS_STATUS register
00167             statusReg = Mma8451q.read_single( MMA8451_PL_STATUS );
00168 
00169             /* Display Orientation of NAMote on Serial Port */
00170             SerialAcclMetrDisplay( statusReg );
00171 
00172             // If Orientation of the Mote changed then populate Upper Nibble of 0th Byte of Tx Buffer
00173             if( ( statusReg & 0x40 ) != 0 )
00174             {   
00175                 AppLed = 0;
00176                 CtrlLED( Green, LED_OFF );
00177                 BuffAddr[BuffPtr++] = 0; // horizontal
00178             }
00179             else
00180             {
00181                 AppLed = 1;
00182                 CtrlLED( Green, LED_ON );
00183                 BuffAddr[BuffPtr++] = 10; // vertical
00184             }
00185             break;
00186         }
00187 
00188         case AppPushButton:
00189         {
00190             uint16_t PushButtonCnt;
00191             uint8_t *p = ( uint8_t * )&PushButtonCnt;
00192 
00193             PushButtonCnt = LoRaMacUplinkStatus.UplinkCounter;
00194 
00195             memcpy( &BuffAddr[BuffPtr], p, sizeof( uint16_t ) );
00196             break;
00197         }
00198 
00199         default:
00200         {
00201             break;
00202         }
00203     }
00204 }
00205 
00206 static void OnRedLedTimerEvent( void )
00207 {
00208     TimerStop( &RedLedTimer.LedTimer );
00209 
00210     if( RedLed == LED_OFF )
00211     {
00212         RedLed = LED_ON;
00213     }
00214     else
00215     {
00216         RedLed = LED_OFF;
00217     }
00218 }
00219 
00220 static void OnYellowLedTimerEvent( void )
00221 {
00222     TimerStop( &YellowLedTimer.LedTimer );
00223 
00224     if( YellowLed == LED_OFF )
00225     {
00226         YellowLed = LED_ON;
00227     }
00228     else
00229     {
00230         YellowLed = LED_OFF;
00231     }
00232 }
00233 
00234 static void OnGreenLedTimerEvent( void )
00235 {
00236     TimerStop( &GreenLedTimer.LedTimer );
00237 
00238     if( GreenLed == LED_OFF )
00239     {
00240         GreenLed = LED_ON;
00241     }
00242     else
00243     {
00244         GreenLed = LED_OFF;
00245     }
00246 }
00247 
00248 TimerLed::TimerLed( eLedType led )
00249 {
00250     switch( led )
00251     {
00252         case Red:
00253         {
00254             TimerInit( &LedTimer, OnRedLedTimerEvent );
00255             break;
00256         }
00257 
00258         case Yellow:
00259         {
00260             TimerInit( &LedTimer, OnYellowLedTimerEvent );
00261             break;
00262         }
00263 
00264         case Green:
00265         {
00266             TimerInit( &LedTimer, OnGreenLedTimerEvent );
00267             break;
00268         }
00269         default:
00270         {
00271             break;
00272         }
00273     }
00274     
00275 }
00276         
00277 TimerLed::~TimerLed( )
00278 {
00279 }
00280 
00281 void BlinkLED( eLedType led, uint32_t time )
00282 {
00283     switch( led )
00284     {
00285         case Red:
00286         {
00287             TimerSetValue( &RedLedTimer.LedTimer, time );
00288             TimerStart( &RedLedTimer.LedTimer );
00289             RedLed = LED_ON;
00290             break;
00291         }
00292 
00293         case Yellow:
00294         {
00295             TimerSetValue( &YellowLedTimer.LedTimer, time );
00296             TimerStart( &YellowLedTimer.LedTimer );
00297             YellowLed = LED_ON;
00298             break;
00299         }
00300 
00301         case Green:
00302         {
00303             TimerSetValue( &GreenLedTimer.LedTimer, time );
00304             TimerStart( &GreenLedTimer.LedTimer );
00305             GreenLed = LED_ON;
00306             break;
00307         }
00308         default:
00309         {
00310             break;
00311         }
00312     }
00313 }
00314 
00315 void ToggleLED( eLedType led )
00316 {
00317     switch( led )
00318     {
00319         case Red:
00320         {
00321             if( RedLed == LED_OFF )
00322             {
00323                 RedLed = LED_ON;
00324             }
00325             else
00326             {
00327                 RedLed = LED_OFF;
00328             }
00329             break;
00330         }
00331 
00332         case Yellow:
00333         {
00334             if( YellowLed == LED_OFF )
00335             {
00336                 YellowLed = LED_ON;
00337             }
00338             else
00339             {
00340                 YellowLed = LED_OFF;
00341             }
00342             break;
00343         }
00344 
00345         case Green:
00346         {
00347             if( GreenLed == LED_OFF )
00348             {
00349                 GreenLed = LED_ON;
00350             }
00351             else
00352             {
00353                 GreenLed = LED_OFF;
00354             }
00355             break;
00356         }
00357         default:
00358         {
00359             break;
00360         }
00361     }
00362 }   
00363 
00364 void CtrlLED( eLedType led, uint8_t state )
00365 {
00366     switch( led )
00367     {
00368         case Red:
00369         {
00370             RedLed = state;
00371             break;
00372         }
00373 
00374         case Yellow:
00375         {
00376             YellowLed = state;
00377             break;
00378         }
00379 
00380         case Green:
00381         {
00382             GreenLed = state;
00383             break;
00384         }
00385 
00386         case Usr:
00387         {
00388             if( state )
00389             {
00390                 UsrLed = LED_ON;
00391             }
00392             else
00393             {
00394                 UsrLed = LED_OFF;
00395             }
00396             break;
00397         }
00398     }
00399 }
00400 
00401 void CheckOrientation( void )
00402 {
00403     uint8_t statusReg; 
00404 
00405     // Read the PS_STATUS register
00406     statusReg = Mma8451q.read_single( MMA8451_PL_STATUS );
00407 
00408      // If Orientation of the Mote changed then populate Upper Nibble of 0th Byte of Tx Buffer
00409     if( ( statusReg & 0x40 ) != 0 )
00410     {
00411         CtrlLED( Green, LED_OFF );
00412         VerticalStatus = false; // horizontal
00413     }
00414     else
00415     {
00416         CtrlLED( Green, LED_ON );
00417         VerticalStatus = true; // vertical
00418     }
00419 }