aboutsummaryrefslogtreecommitdiff
path: root/GEOLOC/lib
diff options
context:
space:
mode:
Diffstat (limited to 'GEOLOC/lib')
-rw-r--r--GEOLOC/lib/config.c51
-rw-r--r--GEOLOC/lib/config.h62
-rw-r--r--GEOLOC/lib/dragino.c40
-rw-r--r--GEOLOC/lib/dragino.h38
-rw-r--r--GEOLOC/lib/fskconfig.c66
-rw-r--r--GEOLOC/lib/fskconfig.h67
-rw-r--r--GEOLOC/lib/gps.c147
-rw-r--r--GEOLOC/lib/gps.h53
-rw-r--r--GEOLOC/lib/types.h10
9 files changed, 534 insertions, 0 deletions
diff --git a/GEOLOC/lib/config.c b/GEOLOC/lib/config.c
new file mode 100644
index 0000000..b086628
--- /dev/null
+++ b/GEOLOC/lib/config.c
@@ -0,0 +1,51 @@
+#include "config.h"
+
+void applyConfig(Config config){
+
+ // Apply modulation and mode
+ byte reg=readReg(REG_OP_MODE) &0x3F ; // Fetch opmode register and clear modulation and mode bits
+ reg=reg | config.mod; // Apply modulation and mode
+ writeReg(REG_OP_MODE,reg); // Send register back to module
+
+ // Apply carrier frequency
+ int cFreq=config.cFreq/FSTEP;
+ reg=cFreq >> 16 ;
+ writeReg(REG_FRF_MSB,reg); // Send register to module
+ reg=(cFreq&0x00FFFF) >> 8 ;
+ writeReg(REG_FRF_MID,reg); /// Send register to module
+ reg=(cFreq&0x0000FF);
+ writeReg(REG_FRF_LSB,reg); // Send register to module
+
+ // Set LNAGain
+ reg=readReg(REG_LNA) & 0x7F;
+ writeReg(REG_LNA, reg|config.lnaGain);
+
+
+ // Apply PaBoost, max output power and outputPower
+ byte Pmax=round((config.maxPower-10.8)/0.6);
+ Pmax=(Pmax & 0x07)<<4;
+ byte outputPower;
+ if(config.paSelect==PA_SELECT_ON){
+ outputPower=config.outputPower-32;
+ }
+ else{
+ outputPower=config.outputPower-Pmax+15;
+ }
+ outputPower=config.outputPower & 0x0F;
+ reg=config.paSelect|outputPower|Pmax;
+ writeReg(REG_PA_CONFIG, reg);
+
+
+ // Apply FSK configuration
+ if(config.mod==MOD_FSK){
+ applyFSKConfig(config.fsk);
+ }
+}
+
+void applyMode(Config config){
+ // Apply modulation and mode
+ byte reg=readReg(REG_OP_MODE) &0xF8 ; // Fetch opmode register and clear mode
+ reg=config.mode | reg; // Apply mode
+ writeReg(REG_OP_MODE,reg); // Send register back to module
+
+}
diff --git a/GEOLOC/lib/config.h b/GEOLOC/lib/config.h
new file mode 100644
index 0000000..47a7151
--- /dev/null
+++ b/GEOLOC/lib/config.h
@@ -0,0 +1,62 @@
+#ifndef config_h
+#define config_h
+
+#include "dragino.h"
+#include "types.h"
+#include "fskconfig.h"
+#include <math.h>
+
+// Define General Registers
+#define REG_FIFO 0x00
+#define REG_OP_MODE 0x01
+#define REG_VERSION 0x42
+#define REG_FRF_MSB 0x06
+#define REG_FRF_MID 0x07
+#define REG_FRF_LSB 0x08
+#define REG_PA_CONFIG 0x09
+
+// Define General Registers values
+#define MODE_SLEEP 0x00
+#define MODE_STDBY 0x01
+#define MODE_TX 0x03
+#define MODE_RX 0x05
+#define MOD_LORA 0x80
+#define MOD_FSK 0x00
+#define MOD_OOK 0x40
+#define LNA_GAIN_G1 0x20
+#define LNA_GAIN_G2 0x40
+#define LNA_GAIN_G3 0x60
+#define LNA_GAIN_G4 0x80
+#define LNA_GAIN_G5 0xA0
+#define LNA_GAIN_G6 0xC0
+#define PA_SELECT_ON 0x80
+#define PA_SELECT_OFF 0x00
+
+
+
+// Define global configuration
+typedef struct Config Config;
+struct Config {
+ byte mod;
+ byte mode;
+ int cFreq;
+ FSKConfig fsk; // FSK Specific configuration
+ byte lnaGain;
+ byte paSelect;
+ short maxPower;
+ short outputPower;
+ // TODO LORA Specific configuration
+};
+
+
+/**
+ * Apply global configuration (module mode is unchanged here)
+ */
+void applyConfig(Config config);
+
+/**
+ * Change SX1276 mode (SLEEP, TX, RX etc...)
+ */
+void applyMode(Config config);
+
+#endif
diff --git a/GEOLOC/lib/dragino.c b/GEOLOC/lib/dragino.c
new file mode 100644
index 0000000..30de48a
--- /dev/null
+++ b/GEOLOC/lib/dragino.c
@@ -0,0 +1,40 @@
+#include "dragino.h"
+
+
+void initPins(){
+ // Init WiringPi
+ wiringPiSetup();
+ pinMode(NSS_PIN, OUTPUT);
+ pinMode(DIO0_PIN, INPUT);
+ pinMode(RESET_PIN, OUTPUT);
+ wiringPiSPISetup(CHANNEL, BIT_RATE);
+}
+
+byte readReg(byte address){
+ byte buffer[2];
+ buffer[0]=address & 0x7F; // Set read flag (SX1276 datasheet page 80)
+ buffer[1]=0x00;
+
+ digitalWrite(NSS_PIN, LOW);
+ wiringPiSPIDataRW(CHANNEL, buffer, 2);
+ digitalWrite(NSS_PIN, HIGH);
+
+ return(buffer[1]);
+}
+void writeReg(byte address, byte data){
+ byte buffer[2];
+ buffer[0]=address | 0x80; // Set write flag (SX1276 datasheet page 80)
+ buffer[1]=data;
+
+ digitalWrite(NSS_PIN, LOW);
+ wiringPiSPIDataRW(CHANNEL, buffer, 2);
+ digitalWrite(NSS_PIN, HIGH);
+}
+
+void reset(){
+ // SX1276 datasheet page 116
+ digitalWrite(RESET_PIN, LOW);
+ delay(100);
+ digitalWrite(RESET_PIN, HIGH);
+ delay(100);
+}
diff --git a/GEOLOC/lib/dragino.h b/GEOLOC/lib/dragino.h
new file mode 100644
index 0000000..082de14
--- /dev/null
+++ b/GEOLOC/lib/dragino.h
@@ -0,0 +1,38 @@
+#ifndef dragino_h
+#define dragino_h
+
+#include "types.h"
+#include <wiringPi.h>
+#include <wiringPiSPI.h>
+
+// Define WiringPi Parameters
+#define CHANNEL 0
+#define BIT_RATE 500000
+
+// Define dragino shield pin for use SPI protocol (see http://wiki.dragino.com/index.php?title=Lora/GPS_HAT)
+#define NSS_PIN 6
+#define RESET_PIN 0
+#define DIO0_PIN 7
+#define TX_PIN 15
+
+/**
+ * Configure WiringPi for SPI
+ */
+void initPins();
+
+/**
+ * Used to init and reset SX1276
+ */
+void reset();
+
+/**
+ * Read in SX1276 register
+ */
+byte readReg(byte address);
+
+/**
+ * Write in SX1276 register
+ */
+void writeReg(byte address, byte value);
+
+#endif
diff --git a/GEOLOC/lib/fskconfig.c b/GEOLOC/lib/fskconfig.c
new file mode 100644
index 0000000..42f3775
--- /dev/null
+++ b/GEOLOC/lib/fskconfig.c
@@ -0,0 +1,66 @@
+#include "fskconfig.h"
+
+void applyFSKConfig(FSKConfig fsk){
+
+ // Set preambleDetection
+ byte reg=readReg(REG_PREAMBLE_DETECT)&0x7F;
+ writeReg(REG_PREAMBLE_DETECT, fsk.preambleDetection | reg);
+
+ // Set preamble size
+ reg=fsk.preambleSize>>8;
+ writeReg(REG_PREAMBLE_MSB, reg);
+ reg=fsk.preambleSize & 0x00ff;
+ writeReg(REG_PREAMBLE_LSB, reg);
+
+ // Set crcOn
+ reg=readReg(REG_PACKET_CONFIG_1) & 0xEF;
+ writeReg(REG_PACKET_CONFIG_1,reg|fsk.crcOn);
+
+ // Set crc autoclear
+ reg=readReg(REG_PACKET_CONFIG_1) & 0xF7;
+ writeReg(REG_PACKET_CONFIG_1,reg|fsk.crcAutoClearOff);
+
+ // Set payloadLength
+ reg=readReg(REG_PACKET_CONFIG_2) & 0xF8;
+ byte payloadLengthMSB=(fsk.payloadLength >> 8) &0x7;
+ byte payloadLengthLSB=fsk.payloadLength &0xFF;
+ writeReg(REG_PACKET_CONFIG_2,payloadLengthMSB|reg);
+ writeReg(REG_PAYLOAD_LENGTH, payloadLengthLSB);
+
+ // Set fifo threshold
+ reg=readReg(REG_FIFO_THRESH) & 0xC0;
+ reg=reg| (fsk.fifoThreshold & 0x3F);
+ writeReg(REG_FIFO_THRESH,reg);
+
+ // Set fixedPayloadLength
+ reg=readReg(REG_PACKET_CONFIG_1) & 0x7F;
+ writeReg(REG_PACKET_CONFIG_1,reg | fsk.fixedPayloadLength);
+
+ // Set frequency dev
+ short freqDev=fsk.freqDev/FSTEP;
+ byte freqDevMSB=freqDev>>8;
+ byte freqDevLSB=freqDev&0x00FF;
+ writeReg(REG_FDEV_MSB, freqDevMSB);
+ writeReg(REG_FDEV_LSB, freqDevLSB);
+
+ // Apply bitrate //
+ short bitrate=FXOSC/fsk.bitrate;
+ byte bitrateMSB=bitrate>>8;
+ byte bitrateLSB=bitrate & 0x00FF;
+ writeReg(REG_BITRATE_MSB, bitrateMSB);
+ writeReg(REG_BITRATE_LSB, bitrate & 0x0F);
+
+ // Apply rssi smoothing
+ reg=readReg(REG_RSSI_CONFIG) & 0xF8;
+ reg=reg|fsk.rssiSmoothing;
+ writeReg(REG_RSSI_CONFIG,reg);
+
+}
+
+
+int fetchRSSI(){
+ int value=readReg(REG_RSSI_VALUE);
+ value=(-value)/2; // See SX1276 datasheet page 86
+ return(value);
+}
+
diff --git a/GEOLOC/lib/fskconfig.h b/GEOLOC/lib/fskconfig.h
new file mode 100644
index 0000000..ea6d771
--- /dev/null
+++ b/GEOLOC/lib/fskconfig.h
@@ -0,0 +1,67 @@
+#ifndef fskconfig_h
+#define fskconfig_h
+
+#include "dragino.h"
+#include "types.h"
+
+// Define FSK Registers
+#define REG_PREAMBLE_DETECT 0x1f
+#define REG_PREAMBLE_MSB 0x25
+#define REG_PREAMBLE_LSB 0x26
+#define REG_PACKET_CONFIG_1 0x30
+#define REG_PACKET_CONFIG_2 0x31
+#define REG_PAYLOAD_LENGTH 0x32
+#define REG_FIFO_THRESH 0x35
+#define REG_LNA 0x0C
+#define REG_FDEV_MSB 0x04
+#define REG_FDEV_LSB 0x05
+#define REG_BITRATE_MSB 0x02
+#define REG_BITRATE_LSB 0x03
+#define REG_RSSI_CONFIG 0x0E
+#define REG_RSSI_VALUE 0x11
+
+// Define FSK configuration parameters values
+#define CRC_ON 0x10
+#define CRC_OFF 0x00
+#define CRC_AUTOCLEAR_OFF_ON 0x08
+#define CRC_AUTOCLEAR_OFF_OFF 0x00
+#define FIXED_PAYLOAD_LENGTH_ON 0x80
+#define FIXED_PAYLOAD_LENGTH_OFF 0x00
+#define PREAMBLE_DETECTION_ON 0x80
+#define PREAMBLE_DETECTION_OFF 0x00
+#define RSSI_SAMPLE_2 0x00
+#define RSSI_SAMPLE_4 0x01
+#define RSSI_SAMPLE_8 0x02
+#define RSSI_SAMPLE_16 0x03
+#define RSSI_SAMPLE_32 0x04
+#define RSSI_SAMPLE_64 0x05
+#define RSSI_SAMPLE_128 0x06
+#define RSSI_SAMPLE_256 0x07
+
+
+// Define FSK Configuration
+typedef struct FSKConfig FSKConfig;
+struct FSKConfig {
+ byte preambleDetection;
+ short preambleSize;
+ short fifoThreshold;
+ short payloadLength;
+ short freqDev;
+ short bitrate;
+ byte rssiSmoothing;
+ byte crcOn;
+ byte crcAutoClearOff;
+ byte fixedPayloadLength;
+};
+
+/**
+ * Apply FSK configuration
+ */
+void applyFSKConfig(FSKConfig fsk);
+
+/**
+ * Fetch FSK RSSI
+ */
+int fetchRSSI();
+
+#endif
diff --git a/GEOLOC/lib/gps.c b/GEOLOC/lib/gps.c
new file mode 100644
index 0000000..4eec6cc
--- /dev/null
+++ b/GEOLOC/lib/gps.c
@@ -0,0 +1,147 @@
+#include "gps.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <unistd.h>
+
+#define GPS_DEV_FILE "/dev/ttyS0" // Define GPS serial port file
+#define BUFFER_SIZE 100 // Define receive buffer size
+
+/**
+ * Configure UART channel
+ * TODO : Set baud rate to ???? see NMEA datasheet
+ */
+void configSerialPort(int fd){
+ struct termios Termios;
+ tcgetattr(fd,&Termios);
+ Termios.c_lflag |= ICANON;
+ tcsetattr(fd,TCSANOW,&Termios);
+ tcflush(fd, TCIFLUSH); // Clear already received frames
+}
+
+/**
+ * Fetch NMEA Frame type
+ * TODO : Other frame types
+ */
+NMEA_TYPE getNMEA_TYPE(unsigned char *data){
+ unsigned char* typeChar=malloc(sizeof(char)*4);
+ typeChar[3]='\0';
+ memcpy(typeChar, data+3,3);
+ if(strcmp(typeChar, "GGA")==0){
+ return(GGA);
+ }
+ free(typeChar);
+ return(NONE);
+}
+
+/**
+ * Build NMEA frame from array of char
+ * TODO : Other GGA parameters
+ */
+struct NMEA_GGA buildNMEA_GGA(unsigned char *data){
+// data="$GPGGA,095003.000,2055.9571,S,05517.4159,E,1,6,1.59,138.8,M,-9.9,M,,*5D"; // To test !!!
+ struct NMEA_GGA frame;
+ unsigned char *buffer=malloc(sizeof(char)*strlen(data));
+ memcpy(buffer,data,strlen(data));
+
+ short i=1;
+ char *saveP;
+ char *token=strtok_r(buffer,",",&saveP);
+ while(token!=NULL){
+ if(strlen(token)>0){
+ char tmp[6];
+ switch(i){
+ case 2: // Fetch hour, min, sec and ms
+ memcpy(tmp,token,2);tmp[2]='\0';
+ frame.hour=atoi(tmp);
+ memcpy(tmp,token+2,2);
+ frame.min=atoi(tmp);
+ memcpy(tmp,token+4,2);
+ frame.sec=atoi(tmp);
+ memcpy(tmp,token+7,3);tmp[3]='\0';
+ frame.ms=atoi(tmp);
+ break;
+ case 3: // Fetch Latitude
+ memcpy(tmp,token,2);tmp[2]='\0';
+ frame.latDeg=atoi(tmp);
+ memcpy(tmp,token+2,2);
+ frame.latMin=atoi(tmp);
+ memcpy(tmp,token+5,4);tmp[4]='\0';
+ frame.latSec=atoi(tmp);
+ frame.latSec=frame.latSec/10000;
+ frame.latSec=(3600*frame.latSec)/60; // Convertion degrès min en degrès sec
+ break;
+ case 4: // Fetch latitude direction
+ frame.latDir=token[0];
+ break;
+ case 5: // Fetch longitude
+ memcpy(tmp,token,3);tmp[3]='\0';
+ frame.lonDeg=atoi(tmp);
+ tmp[2]='\0';
+ memcpy(tmp,token+3,2);
+ frame.lonMin=atoi(tmp);
+ memcpy(tmp,token+6,4);tmp[4]='\0';
+ frame.lonSec=atoi(tmp);
+ frame.lonSec=frame.lonSec/10000;
+ frame.lonSec=(3600*frame.lonSec)/60; // Convertion degrès min en degrès sec
+ break;
+ case 6: // Fetch longitude direction
+ frame.lonDir=token[0];
+ break;
+ case 7: // Fetch GPS state
+ frame.state=atoi(token);
+ break;
+ case 8: // Fetch number of statellites
+ frame.sats=atoi(token);
+ break;
+ }
+ }
+ token=strtok_r(NULL,",",&saveP);
+ i++;
+ }
+
+ free(buffer);
+ return(frame);
+
+}
+
+/**
+ * Fetch NMEA FRAME
+ */
+struct NMEA_GGA getNMEA_GGAFrame(){
+
+ int fd; // File descriptor
+ const char *device = "/dev/ttyS0";
+ fd = open(device, O_RDWR);
+ if(fd == -1) {
+ printf( "Failed to open gps device.\n" );
+ }
+
+ // Configure the serial port
+ configSerialPort(fd);
+
+ struct NMEA_GGA frame; // Def empty frame
+ short i;
+ // Try to feth the GGA frame (100 times max)
+ for(i=0;i<100;i++){
+ char out[BUFFER_SIZE];
+ memset(out,0,BUFFER_SIZE);
+ read(fd,out,BUFFER_SIZE);
+ if(strlen(out)>1){
+ if(getNMEA_TYPE(out)==GGA){
+ frame=buildNMEA_GGA(out);
+ //if(frame.state!=UNFIXED){
+ // printf("%d:%d:%d:%d\nLat : %d deg %d min %f sec %d Dir\n",frame.hour,frame.min,frame.sec,frame.ms,frame.latDeg,frame.latMin,frame.latSec, frame.latDir);
+ // printf("Lon : %d deg %d min %f sec %d Dir\n",frame.lonDeg,frame.lonMin,frame.lonSec, frame.lonDir);
+ // printf("Sats : %d",frame.sats);
+ // printf("%s",out);
+ //}
+ break; // If the frame is found, exit
+ }
+ }
+ }
+ close(fd);
+ return(frame);
+}
diff --git a/GEOLOC/lib/gps.h b/GEOLOC/lib/gps.h
new file mode 100644
index 0000000..49dbdd6
--- /dev/null
+++ b/GEOLOC/lib/gps.h
@@ -0,0 +1,53 @@
+#ifndef gps_h
+#define gps_h
+
+/**
+ * Define NMEA frame types
+ */
+typedef enum NMEA_TYPE NMEA_TYPE;
+enum NMEA_TYPE { GGA=125,NONE }; // TODO : other frame type
+
+/**
+ * Define compass N,S,E,W
+ */
+typedef enum COMPASS COMPASS;
+enum COMPASS { NORTH=78, SOUTH=83, EAST=69, WEST=87};
+
+/**
+ * Define GPS state
+ */
+typedef enum GPS_STATE GPS_STATE;
+enum GPS_STATE { FIXED_GPS=1, FIXED_DGPS=2, UNFIXED=0};
+
+/**
+ * Define NMEA GGA FRAME
+ */
+struct NMEA_GGA {
+ short hour;
+ short min;
+ short sec;
+ short ms;
+
+ short latDeg;
+ short latMin;
+ float latSec;
+ COMPASS latDir;
+
+ short lonDeg;
+ short lonMin;
+ float lonSec;
+ COMPASS lonDir;
+
+ short sats;
+ GPS_STATE state;
+
+ // TODO : Finish Frame
+
+};
+
+/**
+ * Fetch the last NMEA_GGA frame
+ */
+struct NMEA_GGA getNMEA_GGAFrame();
+
+#endif
diff --git a/GEOLOC/lib/types.h b/GEOLOC/lib/types.h
new file mode 100644
index 0000000..01c0e97
--- /dev/null
+++ b/GEOLOC/lib/types.h
@@ -0,0 +1,10 @@
+#ifndef type_h
+#define type_h
+
+#define FXOSC 32000000 // SX1276 clock frequency (SX1276 datasheet page 14)
+#define FSTEP 61 // Default FSTEP (SX1276 datasheet page 15)
+
+// Define byte size for convenience
+typedef unsigned char byte;
+
+#endif