LoRaWAN smart agriculture application using FRDM-K64F ARM mbed board along with SX1272MB2xAS LoRa shield as the LoRa Node.
Dependencies: DHT11 LMiC SX1272Lib mbed
Fork of LoRaWAN-lmic-app by
hal.cpp@11:dc6e995a7849, 2018-04-11 (annotated)
- Committer:
- GTsapparellas
- Date:
- Wed Apr 11 19:52:17 2018 +0000
- Revision:
- 11:dc6e995a7849
- Parent:
- 6:3758685f4b75
version 1.0 (Commenting)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mluis | 1:60184eda0066 | 1 | /******************************************************************************* |
mluis | 1:60184eda0066 | 2 | * Copyright (c) 2014 IBM Corporation. |
mluis | 1:60184eda0066 | 3 | * All rights reserved. This program and the accompanying materials |
mluis | 1:60184eda0066 | 4 | * are made available under the terms of the Eclipse Public License v1.0 |
mluis | 1:60184eda0066 | 5 | * which accompanies this distribution, and is available at |
mluis | 1:60184eda0066 | 6 | * http://www.eclipse.org/legal/epl-v10.html |
mluis | 1:60184eda0066 | 7 | * |
mluis | 1:60184eda0066 | 8 | * Contributors: |
mluis | 1:60184eda0066 | 9 | * IBM Zurich Research Lab - initial API, implementation and documentation |
mluis | 1:60184eda0066 | 10 | * Semtech Apps Team - Modified to support the MBED sx1276 driver |
mluis | 1:60184eda0066 | 11 | * library. |
mluis | 1:60184eda0066 | 12 | * Possibility to use original or Semtech's MBED |
mluis | 1:60184eda0066 | 13 | * radio driver. The selection is done by setting |
mluis | 1:60184eda0066 | 14 | * USE_SMTC_RADIO_DRIVER preprocessing directive |
mluis | 1:60184eda0066 | 15 | * in lmic.h |
GTsapparellas | 6:3758685f4b75 | 16 | * ///////////////////////////////////////////////////////////////////////////// |
GTsapparellas | 6:3758685f4b75 | 17 | * |
GTsapparellas | 6:3758685f4b75 | 18 | * Used by Giorgos Tsapparellas for Internet of Things (IoT) smart monitoring |
GTsapparellas | 6:3758685f4b75 | 19 | * device for agriculture using LoRaWAN technology. |
GTsapparellas | 6:3758685f4b75 | 20 | * |
GTsapparellas | 6:3758685f4b75 | 21 | * Date of issued copy: 25 January 2018 |
GTsapparellas | 6:3758685f4b75 | 22 | * |
GTsapparellas | 6:3758685f4b75 | 23 | * Modifications: |
GTsapparellas | 6:3758685f4b75 | 24 | * - Modified to meet SX1272MB2xAS LoRa shield's pin allocations. |
GTsapparellas | 6:3758685f4b75 | 25 | * |
GTsapparellas | 6:3758685f4b75 | 26 | * Notice that, connectivity for SX1272MB2xAS LoRa shield is allocated as: |
GTsapparellas | 6:3758685f4b75 | 27 | * SX1272MB2xAS MBED Pin |
GTsapparellas | 6:3758685f4b75 | 28 | * SCK D13 |
GTsapparellas | 6:3758685f4b75 | 29 | * MOSI D11 |
GTsapparellas | 6:3758685f4b75 | 30 | * MISO D12 |
GTsapparellas | 6:3758685f4b75 | 31 | * NSS D10 |
GTsapparellas | 6:3758685f4b75 | 32 | * DIO0 D2 |
GTsapparellas | 6:3758685f4b75 | 33 | * DIO1 D3 |
GTsapparellas | 6:3758685f4b75 | 34 | * DIO2 D4 |
GTsapparellas | 6:3758685f4b75 | 35 | * DIO3 D5 |
GTsapparellas | 6:3758685f4b75 | 36 | * NRESET A0 |
GTsapparellas | 6:3758685f4b75 | 37 | * |
GTsapparellas | 6:3758685f4b75 | 38 | * - Added some external comments for meeting good principles of |
GTsapparellas | 6:3758685f4b75 | 39 | * source code re-usability. |
mluis | 1:60184eda0066 | 40 | *******************************************************************************/ |
GTsapparellas | 6:3758685f4b75 | 41 | |
mluis | 1:60184eda0066 | 42 | #include "mbed.h" |
mluis | 1:60184eda0066 | 43 | #include "lmic.h" |
mluis | 1:60184eda0066 | 44 | #include "mbed_debug.h" |
mluis | 1:60184eda0066 | 45 | |
mluis | 1:60184eda0066 | 46 | #if !USE_SMTC_RADIO_DRIVER |
mluis | 1:60184eda0066 | 47 | |
mluis | 1:60184eda0066 | 48 | extern void radio_irq_handler( u1_t dio ); |
mluis | 1:60184eda0066 | 49 | |
GTsapparellas | 6:3758685f4b75 | 50 | static DigitalOut nss( D10 ); // nss |
mluis | 1:60184eda0066 | 51 | static SPI spi( D11, D12, D13 ); // ( mosi, miso, sclk ) |
mluis | 1:60184eda0066 | 52 | |
GTsapparellas | 6:3758685f4b75 | 53 | static DigitalInOut rst( A0 ); // rst (reset) |
GTsapparellas | 6:3758685f4b75 | 54 | static DigitalOut rxtx( A4 ); // rx and tx |
mluis | 1:60184eda0066 | 55 | |
GTsapparellas | 6:3758685f4b75 | 56 | static InterruptIn dio0( D2 ); // dio0 |
GTsapparellas | 6:3758685f4b75 | 57 | static InterruptIn dio1( D3 ); // dio1 |
GTsapparellas | 6:3758685f4b75 | 58 | static InterruptIn dio2( D4 ); // dio2 |
mluis | 1:60184eda0066 | 59 | |
GTsapparellas | 6:3758685f4b75 | 60 | /* |
GTsapparellas | 6:3758685f4b75 | 61 | * dio0Irq function of type void. |
GTsapparellas | 6:3758685f4b75 | 62 | * |
GTsapparellas | 6:3758685f4b75 | 63 | * Input parameters: None |
GTsapparellas | 6:3758685f4b75 | 64 | * |
GTsapparellas | 6:3758685f4b75 | 65 | */ |
mluis | 1:60184eda0066 | 66 | static void dio0Irq( void ) { |
mluis | 1:60184eda0066 | 67 | radio_irq_handler( 0 ); |
GTsapparellas | 6:3758685f4b75 | 68 | }// end of dio0Irq function. |
mluis | 1:60184eda0066 | 69 | |
GTsapparellas | 6:3758685f4b75 | 70 | /* |
GTsapparellas | 6:3758685f4b75 | 71 | * dio1Irq function of type void. |
GTsapparellas | 6:3758685f4b75 | 72 | * |
GTsapparellas | 6:3758685f4b75 | 73 | * Input parameters: None |
GTsapparellas | 6:3758685f4b75 | 74 | * |
GTsapparellas | 6:3758685f4b75 | 75 | */ |
mluis | 1:60184eda0066 | 76 | static void dio1Irq( void ) { |
mluis | 1:60184eda0066 | 77 | radio_irq_handler( 1 ); |
GTsapparellas | 6:3758685f4b75 | 78 | }// end of dio1Irq funtion. |
mluis | 1:60184eda0066 | 79 | |
GTsapparellas | 6:3758685f4b75 | 80 | /* |
GTsapparellas | 6:3758685f4b75 | 81 | * dio2Irq function of type void. |
GTsapparellas | 6:3758685f4b75 | 82 | * |
GTsapparellas | 6:3758685f4b75 | 83 | * Input parameters: None |
GTsapparellas | 6:3758685f4b75 | 84 | * |
GTsapparellas | 6:3758685f4b75 | 85 | */ |
mluis | 1:60184eda0066 | 86 | static void dio2Irq( void ) { |
mluis | 1:60184eda0066 | 87 | radio_irq_handler( 2 ); |
GTsapparellas | 6:3758685f4b75 | 88 | }// end of dio2Irq function. |
mluis | 1:60184eda0066 | 89 | |
mluis | 1:60184eda0066 | 90 | #endif |
mluis | 1:60184eda0066 | 91 | |
mluis | 1:60184eda0066 | 92 | static u1_t irqlevel = 0; |
mluis | 1:60184eda0066 | 93 | static u4_t ticks = 0; |
mluis | 1:60184eda0066 | 94 | |
mluis | 1:60184eda0066 | 95 | static Timer timer; |
mluis | 1:60184eda0066 | 96 | static Ticker ticker; |
mluis | 1:60184eda0066 | 97 | |
GTsapparellas | 6:3758685f4b75 | 98 | /* |
GTsapparellas | 6:3758685f4b75 | 99 | * reset_timer function of type void. |
GTsapparellas | 6:3758685f4b75 | 100 | * |
GTsapparellas | 6:3758685f4b75 | 101 | * Input parameters: None |
GTsapparellas | 6:3758685f4b75 | 102 | * |
GTsapparellas | 6:3758685f4b75 | 103 | */ |
mluis | 1:60184eda0066 | 104 | static void reset_timer( void ) { |
mluis | 1:60184eda0066 | 105 | ticks += timer.read_us( ) >> 6; |
mluis | 1:60184eda0066 | 106 | timer.reset( ); |
GTsapparellas | 6:3758685f4b75 | 107 | }// end of reset_timer function. |
mluis | 1:60184eda0066 | 108 | |
GTsapparellas | 6:3758685f4b75 | 109 | /* |
GTsapparellas | 6:3758685f4b75 | 110 | * hal_init function of type void. |
GTsapparellas | 6:3758685f4b75 | 111 | * |
GTsapparellas | 6:3758685f4b75 | 112 | * Input parameters: None |
GTsapparellas | 6:3758685f4b75 | 113 | * |
GTsapparellas | 6:3758685f4b75 | 114 | */ |
mluis | 1:60184eda0066 | 115 | void hal_init( void ) { |
mluis | 1:60184eda0066 | 116 | __disable_irq( ); |
mluis | 1:60184eda0066 | 117 | irqlevel = 0; |
mluis | 1:60184eda0066 | 118 | |
mluis | 1:60184eda0066 | 119 | #if !USE_SMTC_RADIO_DRIVER |
GTsapparellas | 6:3758685f4b75 | 120 | // Configure input lines. |
mluis | 1:60184eda0066 | 121 | dio0.mode( PullDown ); |
mluis | 1:60184eda0066 | 122 | dio0.rise( dio0Irq ); |
mluis | 1:60184eda0066 | 123 | dio0.enable_irq( ); |
mluis | 1:60184eda0066 | 124 | dio1.mode( PullDown ); |
mluis | 1:60184eda0066 | 125 | dio1.rise( dio1Irq ); |
mluis | 1:60184eda0066 | 126 | dio1.enable_irq( ); |
mluis | 1:60184eda0066 | 127 | dio2.mode( PullDown ); |
mluis | 1:60184eda0066 | 128 | dio2.rise( dio2Irq ); |
mluis | 1:60184eda0066 | 129 | dio2.enable_irq( ); |
GTsapparellas | 6:3758685f4b75 | 130 | // Configure reset line. |
mluis | 1:60184eda0066 | 131 | rst.input( ); |
GTsapparellas | 6:3758685f4b75 | 132 | // Configure spi. |
mluis | 1:60184eda0066 | 133 | spi.frequency( 8000000 ); |
mluis | 1:60184eda0066 | 134 | spi.format( 8, 0 ); |
mluis | 1:60184eda0066 | 135 | nss = 1; |
mluis | 1:60184eda0066 | 136 | #endif |
GTsapparellas | 6:3758685f4b75 | 137 | // Configure timer. |
mluis | 1:60184eda0066 | 138 | timer.start( ); |
mluis | 1:60184eda0066 | 139 | ticker.attach_us( reset_timer, 10000000 ); // reset timer every 10sec |
mluis | 1:60184eda0066 | 140 | __enable_irq( ); |
GTsapparellas | 6:3758685f4b75 | 141 | }// end of hal_init function. |
mluis | 1:60184eda0066 | 142 | |
mluis | 1:60184eda0066 | 143 | #if !USE_SMTC_RADIO_DRIVER |
mluis | 1:60184eda0066 | 144 | |
GTsapparellas | 6:3758685f4b75 | 145 | /* |
GTsapparellas | 6:3758685f4b75 | 146 | * hal_pin_rxtx function of type void. |
GTsapparellas | 6:3758685f4b75 | 147 | * |
GTsapparellas | 6:3758685f4b75 | 148 | * Input parameters: unsigned char val |
GTsapparellas | 6:3758685f4b75 | 149 | * |
GTsapparellas | 6:3758685f4b75 | 150 | */ |
mluis | 1:60184eda0066 | 151 | void hal_pin_rxtx( u1_t val ) { |
mluis | 1:60184eda0066 | 152 | rxtx = !val; |
GTsapparellas | 6:3758685f4b75 | 153 | }// end of hal_pin_rxtx function. |
mluis | 1:60184eda0066 | 154 | |
GTsapparellas | 6:3758685f4b75 | 155 | /* |
GTsapparellas | 6:3758685f4b75 | 156 | * hal_pin_nss function of type void. |
GTsapparellas | 6:3758685f4b75 | 157 | * |
GTsapparellas | 6:3758685f4b75 | 158 | * Input parameters: unsigned char val |
GTsapparellas | 6:3758685f4b75 | 159 | * |
GTsapparellas | 6:3758685f4b75 | 160 | */ |
mluis | 1:60184eda0066 | 161 | void hal_pin_nss( u1_t val ) { |
mluis | 1:60184eda0066 | 162 | nss = val; |
GTsapparellas | 6:3758685f4b75 | 163 | }// end of hal_pin_nss function. |
mluis | 1:60184eda0066 | 164 | |
GTsapparellas | 6:3758685f4b75 | 165 | /* |
GTsapparellas | 6:3758685f4b75 | 166 | * hal_pin_rst function of type void. |
GTsapparellas | 6:3758685f4b75 | 167 | * |
GTsapparellas | 6:3758685f4b75 | 168 | * Input parameters: unsigned char val |
GTsapparellas | 6:3758685f4b75 | 169 | * |
GTsapparellas | 6:3758685f4b75 | 170 | */ |
mluis | 1:60184eda0066 | 171 | void hal_pin_rst( u1_t val ) { |
mluis | 1:60184eda0066 | 172 | if( val == 0 || val == 1 ) |
mluis | 1:60184eda0066 | 173 | { // drive pin |
mluis | 1:60184eda0066 | 174 | rst.output( ); |
mluis | 1:60184eda0066 | 175 | rst = val; |
mluis | 1:60184eda0066 | 176 | } |
mluis | 1:60184eda0066 | 177 | else |
mluis | 1:60184eda0066 | 178 | { // keep pin floating |
mluis | 1:60184eda0066 | 179 | rst.input( ); |
mluis | 1:60184eda0066 | 180 | } |
GTsapparellas | 6:3758685f4b75 | 181 | }//end of hal_pin_rst function. |
mluis | 1:60184eda0066 | 182 | |
GTsapparellas | 6:3758685f4b75 | 183 | /* |
GTsapparellas | 6:3758685f4b75 | 184 | * hal_spi function of type unsigned char. |
GTsapparellas | 6:3758685f4b75 | 185 | * |
GTsapparellas | 6:3758685f4b75 | 186 | * Input parameters: unsigned char out |
GTsapparellas | 6:3758685f4b75 | 187 | * |
GTsapparellas | 6:3758685f4b75 | 188 | * Return: spi out value |
GTsapparellas | 6:3758685f4b75 | 189 | */ |
mluis | 1:60184eda0066 | 190 | u1_t hal_spi( u1_t out ) { |
mluis | 1:60184eda0066 | 191 | return spi.write( out ); |
GTsapparellas | 6:3758685f4b75 | 192 | }// end of hal_spi function. |
mluis | 1:60184eda0066 | 193 | |
mluis | 1:60184eda0066 | 194 | #endif |
mluis | 1:60184eda0066 | 195 | |
GTsapparellas | 6:3758685f4b75 | 196 | /* |
GTsapparellas | 6:3758685f4b75 | 197 | * hal_disableIRQs function of type void. |
GTsapparellas | 6:3758685f4b75 | 198 | * |
GTsapparellas | 6:3758685f4b75 | 199 | * Input parameters: None |
GTsapparellas | 6:3758685f4b75 | 200 | * |
GTsapparellas | 6:3758685f4b75 | 201 | */ |
mluis | 1:60184eda0066 | 202 | void hal_disableIRQs( void ) { |
mluis | 1:60184eda0066 | 203 | __disable_irq( ); |
mluis | 1:60184eda0066 | 204 | irqlevel++; |
GTsapparellas | 6:3758685f4b75 | 205 | }// end of hal_disableIRQs function. |
mluis | 1:60184eda0066 | 206 | |
GTsapparellas | 6:3758685f4b75 | 207 | /* |
GTsapparellas | 6:3758685f4b75 | 208 | * hal_enableIRQs function of type void. |
GTsapparellas | 6:3758685f4b75 | 209 | * |
GTsapparellas | 6:3758685f4b75 | 210 | * Input parameters: None |
GTsapparellas | 6:3758685f4b75 | 211 | * |
GTsapparellas | 6:3758685f4b75 | 212 | */ |
mluis | 1:60184eda0066 | 213 | void hal_enableIRQs( void ) { |
mluis | 1:60184eda0066 | 214 | if( --irqlevel == 0 ) |
mluis | 1:60184eda0066 | 215 | { |
mluis | 1:60184eda0066 | 216 | __enable_irq( ); |
mluis | 1:60184eda0066 | 217 | } |
GTsapparellas | 6:3758685f4b75 | 218 | }// end of hal_enableIRQs function. |
mluis | 1:60184eda0066 | 219 | |
GTsapparellas | 6:3758685f4b75 | 220 | /* |
GTsapparellas | 6:3758685f4b75 | 221 | * hal_sleep function of type void. |
GTsapparellas | 6:3758685f4b75 | 222 | * |
GTsapparellas | 6:3758685f4b75 | 223 | * Input parameters: None |
GTsapparellas | 6:3758685f4b75 | 224 | * |
GTsapparellas | 6:3758685f4b75 | 225 | */ |
mluis | 1:60184eda0066 | 226 | void hal_sleep( void ) { |
mluis | 1:60184eda0066 | 227 | // NOP |
GTsapparellas | 6:3758685f4b75 | 228 | }// end of hal_sleep function. |
mluis | 1:60184eda0066 | 229 | |
GTsapparellas | 6:3758685f4b75 | 230 | /* |
GTsapparellas | 6:3758685f4b75 | 231 | * hal_ticks function of type unsigned int. |
GTsapparellas | 6:3758685f4b75 | 232 | * |
GTsapparellas | 6:3758685f4b75 | 233 | * Input parameters: None |
GTsapparellas | 6:3758685f4b75 | 234 | * Return: t value |
GTsapparellas | 6:3758685f4b75 | 235 | * |
GTsapparellas | 6:3758685f4b75 | 236 | */ |
mluis | 1:60184eda0066 | 237 | u4_t hal_ticks( void ) { |
mluis | 1:60184eda0066 | 238 | hal_disableIRQs( ); |
mluis | 1:60184eda0066 | 239 | int t = ticks + ( timer.read_us( ) >> 6 ); |
mluis | 1:60184eda0066 | 240 | hal_enableIRQs( ); |
mluis | 1:60184eda0066 | 241 | return t; |
GTsapparellas | 6:3758685f4b75 | 242 | }//end of hal_ticks function. |
mluis | 1:60184eda0066 | 243 | |
GTsapparellas | 6:3758685f4b75 | 244 | /* |
GTsapparellas | 6:3758685f4b75 | 245 | * deltaticks function of type unsigned short. |
GTsapparellas | 6:3758685f4b75 | 246 | * |
GTsapparellas | 6:3758685f4b75 | 247 | * Input parameters: unsigned int time |
GTsapparellas | 6:3758685f4b75 | 248 | * Return: d time |
GTsapparellas | 6:3758685f4b75 | 249 | */ |
mluis | 1:60184eda0066 | 250 | static u2_t deltaticks( u4_t time ) { |
mluis | 1:60184eda0066 | 251 | u4_t t = hal_ticks( ); |
mluis | 1:60184eda0066 | 252 | s4_t d = time - t; |
mluis | 1:60184eda0066 | 253 | if( d <= 0 ) { |
mluis | 1:60184eda0066 | 254 | return 0; // in the past |
mluis | 1:60184eda0066 | 255 | } |
mluis | 1:60184eda0066 | 256 | if( ( d >> 16 ) != 0 ) { |
mluis | 1:60184eda0066 | 257 | return 0xFFFF; // far ahead |
mluis | 1:60184eda0066 | 258 | } |
mluis | 1:60184eda0066 | 259 | return ( u2_t )d; |
GTsapparellas | 6:3758685f4b75 | 260 | }// end of deltaticks function. |
mluis | 1:60184eda0066 | 261 | |
GTsapparellas | 6:3758685f4b75 | 262 | /* |
GTsapparellas | 6:3758685f4b75 | 263 | * hal_waitUntil function of type void. |
GTsapparellas | 6:3758685f4b75 | 264 | * |
GTsapparellas | 6:3758685f4b75 | 265 | * Input parameters: unsigned int time |
GTsapparellas | 6:3758685f4b75 | 266 | * |
GTsapparellas | 6:3758685f4b75 | 267 | */ |
mluis | 1:60184eda0066 | 268 | void hal_waitUntil( u4_t time ) { |
mluis | 1:60184eda0066 | 269 | while( deltaticks( time ) != 0 ); // busy wait until timestamp is reached |
GTsapparellas | 6:3758685f4b75 | 270 | }// end of hal_waitUntil function. |
mluis | 1:60184eda0066 | 271 | |
GTsapparellas | 6:3758685f4b75 | 272 | /* |
GTsapparellas | 6:3758685f4b75 | 273 | * hal_checkTimer function of type unsigned char. |
GTsapparellas | 6:3758685f4b75 | 274 | * |
GTsapparellas | 6:3758685f4b75 | 275 | * Input parameters: unsigned int time |
GTsapparellas | 6:3758685f4b75 | 276 | * Return: deltaticks time |
GTsapparellas | 6:3758685f4b75 | 277 | * |
GTsapparellas | 6:3758685f4b75 | 278 | */ |
mluis | 1:60184eda0066 | 279 | u1_t hal_checkTimer( u4_t time ) { |
mluis | 1:60184eda0066 | 280 | return ( deltaticks( time ) < 2 ); |
GTsapparellas | 6:3758685f4b75 | 281 | }// end of hal_checkTimer function. |
mluis | 1:60184eda0066 | 282 | |
GTsapparellas | 6:3758685f4b75 | 283 | /* |
GTsapparellas | 6:3758685f4b75 | 284 | * hal_failed function of type void. |
GTsapparellas | 6:3758685f4b75 | 285 | * |
GTsapparellas | 6:3758685f4b75 | 286 | * Input parameters: None |
GTsapparellas | 6:3758685f4b75 | 287 | * |
GTsapparellas | 6:3758685f4b75 | 288 | */ |
mluis | 1:60184eda0066 | 289 | void hal_failed( void ) { |
mluis | 1:60184eda0066 | 290 | while( 1 ); |
GTsapparellas | 6:3758685f4b75 | 291 | }// end of hal_failed function. |