Driver for the SX1276 RF Transceiver

Dependents:   LoRa_PIR LoRaWAN-lmic-app SX1276PingPong LoRaWAN-lmic-app ... more

Files at this revision

API Documentation at this revision

Comitter:
GregCr
Date:
Mon Oct 13 07:06:55 2014 +0000
Parent:
9:b420e9c3d6fe
Commit message:
Added LICENSE.txt; Minor corrections;

Changed in this revision

LICENSE.txt Show annotated file Show diff for this revision Revisions of this file
debug/debug.h Show annotated file Show diff for this revision Revisions of this file
radio/radio.cpp Show annotated file Show diff for this revision Revisions of this file
radio/radio.h Show annotated file Show diff for this revision Revisions of this file
sx1276/sx1276-hal.cpp Show annotated file Show diff for this revision Revisions of this file
sx1276/sx1276-hal.h Show annotated file Show diff for this revision Revisions of this file
sx1276/sx1276.cpp Show annotated file Show diff for this revision Revisions of this file
sx1276/sx1276.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LICENSE.txt	Mon Oct 13 07:06:55 2014 +0000
@@ -0,0 +1,25 @@
+--- Revised BSD License ---
+Copyright (c) 2014, SEMTECH S.A.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of the Semtech corporation nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL SEMTECH S.A. BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debug/debug.h	Mon Oct 13 07:06:55 2014 +0000
@@ -0,0 +1,61 @@
+/* Copyright (c) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+ 
+#ifndef DEBUG_H
+#define DEBUG_H
+
+/** @file debug.h */
+
+#ifndef NDEBUG
+
+#include <stdarg.h>
+#include <stdio.h>
+
+/** Output a debug message
+ * 
+ * @param format printf-style format string, followed by variables
+ */
+static inline void debug(const char *format, ...) {
+    va_list args;
+    va_start(args, format);
+    vfprintf(stderr, format, args);
+    va_end(args);
+}
+
+/** Conditionally output a debug message
+ * 
+ * @param condition output only if condition is true
+ * @param format printf-style format string, followed by variables
+ */
+static inline void debug_if(bool condition, const char *format, ...) {
+    if(condition) {
+        va_list args;
+        va_start(args, format);
+        vfprintf(stderr, format, args);
+        va_end(args);
+    }
+}
+
+#else
+
+static inline void debug(const char *format, ...) {}
+static inline void debug(bool condition, const char *format, ...) {}
+
+#endif
+
+#endif
--- a/radio/radio.cpp	Fri Sep 26 12:59:57 2014 +0000
+++ b/radio/radio.cpp	Mon Oct 13 07:06:55 2014 +0000
@@ -15,7 +15,7 @@
 #include "radio.h"
 
 Radio::Radio( void ( *txDone )( ), void ( *txTimeout ) ( ), void ( *rxDone ) ( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ), 
-			  void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( ) )
+			  void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( bool ChannelActivityDetected ) )
 {
 	this->txDone = txDone;
 	this->txTimeout = txTimeout;
--- a/radio/radio.h	Fri Sep 26 12:59:57 2014 +0000
+++ b/radio/radio.h	Mon Oct 13 07:06:55 2014 +0000
@@ -71,8 +71,10 @@
 
     /*!
      * @brief CAD Done callback prototype.
+     *
+     * @param [IN] ChannelDetected    Channel Activity detected during the CAD
      */
-    void ( *cadDone ) ( );
+    void ( *cadDone ) ( bool ChannelActivityDetected );
 	
 public:
 	//-------------------------------------------------------------------------
@@ -87,7 +89,7 @@
 	 * @param [IN]	rxError
 	 */
 	Radio( void ( *txDone )( ), void ( *txTimeout ) ( ), void ( *rxDone ) ( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ), 
-		   void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( ) );
+		   void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( bool ChannelActivityDetected ) );
 	virtual ~Radio( ) {};
 
 	//-------------------------------------------------------------------------
--- a/sx1276/sx1276-hal.cpp	Fri Sep 26 12:59:57 2014 +0000
+++ b/sx1276/sx1276-hal.cpp	Mon Oct 13 07:06:55 2014 +0000
@@ -34,18 +34,16 @@
 };
 
 SX1276MB1xAS::SX1276MB1xAS( void ( *txDone )( ), void ( *txTimeout ) ( ), void ( *rxDone ) ( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ), 
-                            void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( ),
+                            void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( bool ChannelActivityDetected ),
                             PinName mosi, PinName miso, PinName sclk, PinName nss, PinName reset,
                             PinName dio0, PinName dio1, PinName dio2, PinName dio3, PinName dio4, PinName dio5,
                             PinName antSwitch )
                             : SX1276( txDone, txTimeout, rxDone, rxTimeout, rxError, fhssChangeChannel, cadDone, mosi, miso, sclk, nss, reset, dio0, dio1, dio2, dio3, dio4, dio5),
                             antSwitch( antSwitch ),
-                        #if( defined ( TARGET_KL25Z ) ||  defined ( TARGET_LPC11U6X ) )
+                        #if( defined ( TARGET_NUCLEO_L152RE ) )
+                            fake( D8 ) 
+                        #else
                             fake( A3 )
-                        #elif defined ( TARGET_NUCLEO_L152RE )
-                            fake( D8 )
-                        #else
-                            #warning "Check availability of IRQs on your selected board"
                         #endif
 {
     Reset( );
@@ -66,17 +64,15 @@
 }
 
 SX1276MB1xAS::SX1276MB1xAS( void ( *txDone )( ), void ( *txTimeout ) ( ), void ( *rxDone ) ( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ), 
-                            void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( ) ) 
-                        #if( defined ( TARGET_KL25Z ) ||  defined ( TARGET_LPC11U6X ) )
-                        :   SX1276( txDone, txTimeout, rxDone, rxTimeout, rxError, fhssChangeChannel, cadDone, D11, D12, D13, D10, A0, D2, D3, D4, D5, D8, D9 ),
-                            antSwitch( A4 ), 
-                            fake( A3 )
-                        #elif defined ( TARGET_NUCLEO_L152RE )
+                            void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( bool ChannelActivityDetected ) ) 
+                        #if defined ( TARGET_NUCLEO_L152RE )
                         :   SX1276( txDone, txTimeout, rxDone, rxTimeout, rxError, fhssChangeChannel, cadDone, D11, D12, D13, D10, A0, D2, D3, D4, D5, A3, D9 ), // For NUCLEO L152RE dio4 is on port A3
                             antSwitch( A4 ),
                             fake( D8 )
                         #else
-                            #warning "Check availability of IRQs on your selected board"
+                        :   SX1276( txDone, txTimeout, rxDone, rxTimeout, rxError, fhssChangeChannel, cadDone, D11, D12, D13, D10, A0, D2, D3, D4, D5, D8, D9 ),
+                            antSwitch( A4 ), 
+                            fake( A3 )
                         #endif
 {
     Reset( );
--- a/sx1276/sx1276-hal.h	Fri Sep 26 12:59:57 2014 +0000
+++ b/sx1276/sx1276-hal.h	Mon Oct 13 07:06:55 2014 +0000
@@ -34,12 +34,12 @@
     
 public:
     SX1276MB1xAS( void ( *txDone )( ), void ( *txTimeout ) ( ), void ( *rxDone ) ( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ), 
-                  void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( ),
+                  void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( bool ChannelActivityDetected ),
             PinName mosi, PinName miso, PinName sclk, PinName nss, PinName reset,
             PinName dio0, PinName dio1, PinName dio2, PinName dio3, PinName dio4, PinName dio5,
             PinName antSwitch ); 
             SX1276MB1xAS( void ( *txDone )( ), void ( *txTimeout ) ( ), void ( *rxDone ) ( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ),
-                          void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( ) );
+                          void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( bool ChannelActivityDetected ) );
     virtual ~SX1276MB1xAS( ) { };
     
     protected:
--- a/sx1276/sx1276.cpp	Fri Sep 26 12:59:57 2014 +0000
+++ b/sx1276/sx1276.cpp	Mon Oct 13 07:06:55 2014 +0000
@@ -41,7 +41,7 @@
 
 
 SX1276::SX1276( void ( *txDone )( ), void ( *txTimeout ) ( ), void ( *rxDone ) ( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ), 
-				void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( ),
+				void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( bool ChannelActivityDetected ),
 			    PinName mosi, PinName miso, PinName sclk, PinName nss, PinName reset,
                 PinName dio0, PinName dio1, PinName dio2, PinName dio3, PinName dio4, PinName dio5 )
 			:   Radio( txDone, txTimeout, rxDone, rxTimeout, rxError, fhssChangeChannel, cadDone ),
@@ -888,8 +888,9 @@
                                         RFLR_IRQFLAGS_VALIDHEADER |
                                         RFLR_IRQFLAGS_TXDONE |
                                         //RFLR_IRQFLAGS_CADDONE |
-                                        RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
-                                        RFLR_IRQFLAGS_CADDETECTED );
+                                        RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL // |
+                                        //RFLR_IRQFLAGS_CADDETECTED 
+                                        );
                                           
             // DIO3=CADDone
             Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_00 );
@@ -972,7 +973,8 @@
 	    case MODEM_LORA:
 	        SetOpMode( RF_OPMODE_SLEEP );
 	        Write( REG_OPMODE, ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_ON );
-	
+			Write( 0x30, 0x00 ); //  IF = 0
+	        Write( REG_LR_DETECTOPTIMIZE, ( Read( REG_LR_DETECTOPTIMIZE ) & 0x7F ) ); // Manual IF
 	        Write( REG_DIOMAPPING1, 0x00 );
 	        Write( REG_DIOMAPPING2, 0x00 );
 	        break;
@@ -1372,11 +1374,23 @@
     case MODEM_FSK:
         break;
     case MODEM_LORA:
-        // Clear Irq
-        Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE );
-        if( ( cadDone != NULL ) )
-        {
-            cadDone( );
+    	if( ( Read( REG_LR_IRQFLAGS ) & 0x01 ) == 0x01 )
+    	{
+	        // Clear Irq
+    		Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED_MASK | RFLR_IRQFLAGS_CADDONE);
+	        if( ( cadDone != NULL ) )
+	        {
+	            cadDone( true );
+	        }
+        }
+        else
+        {		
+	        // Clear Irq
+	        Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE );
+	        if( ( cadDone != NULL ) )
+	        {
+	            cadDone( false );
+	        }
         }
         break;
     default:
--- a/sx1276/sx1276.h	Fri Sep 26 12:59:57 2014 +0000
+++ b/sx1276/sx1276.h	Mon Oct 13 07:06:55 2014 +0000
@@ -103,11 +103,11 @@
 
 public:
 	SX1276( void ( *txDone )( ), void ( *txTimeout ) ( ), void ( *rxDone ) ( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ), 
-			void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( ),
+			void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( bool ChannelActivityDetected ),
 			PinName mosi, PinName miso, PinName sclk, PinName nss, PinName reset,
             PinName dio0, PinName dio1, PinName dio2, PinName dio3, PinName dio4, PinName dio5 ); 
     SX1276( void ( *txDone )( ), void ( *txTimeout ) ( ), void ( *rxDone ) ( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ), 
-            void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( ) );
+            void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( bool ChannelActivityDetected ) );
 	virtual ~SX1276( );
 	
 	//-------------------------------------------------------------------------