Claragh Patton Kelly / Mbed 2 deprecated FYP_2

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
claragh_patton
Date:
Wed Apr 25 09:35:02 2018 +0000
Commit message:
First Commit

Changed in this revision

BMP280.cpp Show annotated file Show diff for this revision Revisions of this file
BMP280.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
spi1278.cpp Show annotated file Show diff for this revision Revisions of this file
spi1278.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BMP280.cpp	Wed Apr 25 09:35:02 2018 +0000
@@ -0,0 +1,110 @@
+#include "mbed.h"
+#include "BMP280.h"
+#define BMP280_R_ADDRESS (0x76 << 1)
+//Serial pc(USBTX, USBRX);
+//DigitalOut myled(LED1);
+//I2C i2c(D0,D1); // create new I2C instance and initialise
+I2C i2c(D0,D1); // create new I2C instance and initialise
+
+
+ BMP280::BMP280()//constructor
+ {
+     ReadCalibrationData();
+     //pc.printf("\n\r hello");
+     //MAY NEED MORE CONFIG STEPS
+}    
+int BMP280::BMP280RegisterWrite(uint8_t RegNum, uint8_t Value)
+{
+        //sends a byte to a specific register
+        uint8_t Buffer[2];
+        Buffer[0]= RegNum;
+        Buffer[1]= Value;
+        //send the register address, followed by the data
+        int nack;
+        nack = i2c.write(BMP280_R_ADDRESS,(const char*) Buffer,2,true);
+        return(nack);
+        //nack = i2c.write(BMP280_R_ADDRESS,&rx,1,true);
+    
+}
+int BMP280::BMP280RegisterRead(uint8_t RegNum, uint8_t *Value)
+{
+        //reads a series of bytes, starting from a specific register
+        int nack;
+        nack = i2c.write(BMP280_R_ADDRESS,(const char*)&RegNum,1,true);//send the slave write address and the configuration register address
+        nack = i2c.read(BMP280_R_ADDRESS,(char*)Value,1);// read a byte from the register and store in buffer
+        return(nack);
+}
+     
+void BMP280::ReadCalibrationData()
+{
+    int i;
+    for(i=0;i<26;i++)
+    {
+        BMP280RegisterRead(CAL_START+i, &CalibrationData[i]);
+        //Read calibration table
+    }        
+    dig_T1= (uint16_t ((CalibrationData[1])<<8) + uint16_t (CalibrationData[0]));
+    dig_T2= (uint16_t ((CalibrationData[3])<<8) + uint16_t (CalibrationData[2]));
+    dig_T3= (uint16_t ((CalibrationData[5])<<8) + uint16_t (CalibrationData[4]));
+    dig_P1= (uint16_t ((CalibrationData[7])<<8) + uint16_t (CalibrationData[6]));
+    dig_P2= (uint16_t ((CalibrationData[9])<<8) + uint16_t (CalibrationData[8]));
+    dig_P3= (uint16_t ((CalibrationData[11])<<8)+ uint16_t (CalibrationData[10]));
+    dig_P4= (uint16_t ((CalibrationData[13])<<8)+ uint16_t (CalibrationData[12]));
+    dig_P5= (uint16_t ((CalibrationData[15])<<8)+ uint16_t (CalibrationData[14]));
+    dig_P6= (uint16_t ((CalibrationData[17])<<8)+ uint16_t (CalibrationData[16]));
+    dig_P7= (uint16_t ((CalibrationData[19])<<8)+ uint16_t (CalibrationData[18]));
+    dig_P8= (uint16_t ((CalibrationData[21])<<8)+ uint16_t (CalibrationData[20]));
+    dig_P9= (uint16_t (CalibrationData [23]<<8)+  uint16_t (CalibrationData[22]));
+}
+
+long t_fine;//global temperature variable  
+  
+double BMP280::ReadTemperature(){
+    //function to read the temperature in BMP280, calibrate it and return the value in Celsius
+    BMP280RegisterWrite (0xF4, 0x2E);// Initializing the write register for temperature
+    uint8_t status =0x08;
+    //Start the i2c transmission
+    while(status &0x08){
+        BMP280RegisterRead(0xF3, &status);
+    }
+    //Temperature reading transmitted in 3 parts - MSB, LSB & XLSB
+    uint8_t TemperatureMSB,TemperatureLSB, TemperatureXLSB;
+    BMP280RegisterRead(0xFA, &TemperatureMSB);
+    BMP280RegisterRead(0xFB, &TemperatureLSB);
+    BMP280RegisterRead(0xFC, &TemperatureXLSB);
+    
+    //Convert temperature data bytes to 20-bits within 32 bit integer
+    long RawTemperature = (((long)TemperatureMSB<<16)+((long)TemperatureLSB<<8)+(long)TemperatureXLSB)>>4;
+    //Temperature offset calculations
+    double var1 = (((double)RawTemperature) / 16384.0 - ((double)dig_T1) / 1024.0) * ((double)dig_T2);
+    double var2 = ((((double)RawTemperature) / 131072.0 - ((double)dig_T1) / 8192.0) *
+                 (((double)RawTemperature) / 131072.0 - ((double)dig_T1) / 8192.0)) * ((double)dig_T3);
+    t_fine = (long)(var1 + var2);
+
+    return (var1 + var2) / 5120.0; // Returns Temperature in Celsius
+}
+    
+double BMP280::ReadPressure(){
+    ReadTemperature();//Pressure reading needs the temperature reading to calculate pressure
+    //Start i2c transmission
+    
+    uint8_t PressureMSB,PressureLSB, PressureXLSB;
+    BMP280RegisterRead(0xF7, &PressureMSB);
+    BMP280RegisterRead(0xF8, &PressureLSB);
+    BMP280RegisterRead(0xF9, &PressureXLSB);
+    //Convert temperature data bytes to 20-bits within 32 bit integer
+    uint32_t RawPressure = (((uint32_t)PressureMSB<<16)+((uint32_t)PressureLSB<<8)+((uint32_t)PressureXLSB))>>4;
+    //Pressure offset calculations
+    double var1 = ((double)t_fine / 2.0) - 64000.0;
+    double var2 = var1 * var1 * ((double)dig_P6) / 32768.0;
+    var2 = var2 + var1 * ((double)dig_P5) * 2.0;
+    var2 = (var2 / 4.0) + (((double)dig_P4) * 65536.0);
+    var1 = (((double) dig_P3) * var1 * var1 / 524288.0 + ((double) dig_P2) * var1) / 524288.0;
+    var1 = (1.0 + var1 / 32768.0) * ((double)dig_P1);
+    double p = 1048576.0 - (double)RawPressure;
+    p = (p - (var2 / 4096.0)) * 6250.0 / var1;
+    var1 = ((double) dig_P9) * p * p / 2147483648.0;
+    var2 = p * ((double) dig_P8) / 32768.0;
+    return (p + (var1 + var2 + ((double)dig_P7)) / 16.0) / 100; // pressure in hPa
+    //return RawPressure;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BMP280.h	Wed Apr 25 09:35:02 2018 +0000
@@ -0,0 +1,37 @@
+#include "mbed.h"
+#define BMP280_R_ADDRESS (0x76 << 1)
+//DigitalOut myled(LED1);
+
+
+ class BMP280
+ {
+    public:
+    BMP280();
+    //Declaring Parameters
+    double ReadPressure();
+    double ReadTemperature();
+    double RawPressure();
+    double RawTemperature();
+    int BMP280RegisterWrite(uint8_t RegNum, uint8_t Value);//Declaring Write Register
+    int BMP280RegisterRead(uint8_t RegNum, uint8_t *Value);//Declaring Read Register
+    private:
+    #define CAL_START 0x88 //Defining the address where the calibration data should start 
+    
+    //Reads factory calibration data
+    void ReadCalibrationData();
+    uint8_t CalibrationData[26];//Creating an array of 26 calibration addresses
+    //Declaring calibration for temperature & pressure
+    uint16_t dig_T1;//calibration for temperature
+    int16_t  dig_T2;//calibration for temperature
+    int16_t  dig_T3;//calibration for temperature
+    uint16_t dig_P1;//calibration for pressure
+    int16_t  dig_P2;//calibration for pressure
+    int16_t  dig_P3;//calibration for pressure
+    int16_t  dig_P4;//calibration for pressure
+    int16_t  dig_P5;//calibration for pressure
+    int16_t  dig_P6;//calibration for pressure
+    int16_t  dig_P7;//calibration for pressure
+    int16_t  dig_P8;//calibration for pressure
+    int16_t  dig_P9;//calibration for pressure
+     };   
+ 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Apr 25 09:35:02 2018 +0000
@@ -0,0 +1,77 @@
+#include "mbed.h"
+#include "spi1278.h"
+#include "BMP280.h"
+#define BMP280_R_ADDRESS (0x76 << 1)
+
+
+//Serial pc(USBTX, USBRX);
+//I2C i2c(D0,D1); // create new I2C instance and initialise  
+SPI spi(PA_12, PA_6, PA_5); // mosi, miso, sclk,
+DigitalOut cs(PB_0); 
+DigitalOut rs(PB_4); 
+sx1278_t sx1278;
+uint32_t Counter = 0;
+char Buffer[120];
+extern I2C i2c;
+Serial pc(USBTX, USBRX);
+//Ticker t;
+BMP280 MyBMP; 
+
+DigitalOut myled(LED1);
+
+void wakeup()
+{
+    sx1278_beginPacket(&sx1278, 0);
+        //sprintf(Buffer,"Pkt:%u\n\rTemperature:%f\n\rPressure:%f",Counter, MyBMP.ReadTemperature(), MyBMP.ReadPressure());
+        Counter++;
+        sx1278_write(&sx1278,(uint8_t *)Buffer, strlen(Buffer));        
+        sx1278_endPacket(&sx1278);
+}
+
+int main() {
+    //BMP280
+    i2c.frequency(100000);       // I2C Fast Mode - 400kHz??
+    MyBMP.BMP280RegisterWrite (0xF4, 0xB6);
+    //t.attach(&wakeup, 2.0);
+        
+        uint8_t rx = 0xD0;
+        wait(0.001); 
+        wait(0.0001); 
+        //MyBMP.BMP280RegisterRead (0x, &rx);
+        //MyBMP.ReadPressure();
+        //MyBMP.ReadTemperature();
+        //pc.printf("\n\r RX %f", MyBMP.ReadPressure());
+        //
+        
+            //LoRa 
+    cs = 1; // Chip must be deselected
+    
+    // Setup the spi for 8 bit data, high steady state clock,
+    // second edge capture, with a 1MHz clock rate
+    sx1278._frequency=433123000;
+    spi.format(8,3);
+    spi.frequency(100000);
+    sx1278_init(&sx1278);
+    sx1278_setSpreadingFactor(&sx1278,12);
+    sx1278_setSignalBandwidth(&sx1278,125000);
+    sx1278_setCodingRate4(&sx1278,5);
+    
+    while(1){
+        myled=1;
+        wait(1);
+        sx1278_beginPacket(&sx1278, 0);
+        myled=0;
+        //sprintf(Buffer,"Pkt:%u\n\rT:%d\n\rP:%d\r\n",Counter, 0, 1);
+        //sprintf(Buffer,"Pkt:%f\n\r",(float)Counter);
+        
+        sprintf(Buffer,"Pkt:%u\n\rTemperature:[%f]\n\rPressure:[%f]",Counter, MyBMP.ReadTemperature(), MyBMP.ReadPressure());
+        Counter++;
+        sx1278_write(&sx1278,(uint8_t *)Buffer, strlen(Buffer));        
+        sx1278_endPacket(&sx1278);
+        //asm("wfi");
+        
+        wait(1);//delay
+        sx1278_displayRegisters(&sx1278);
+    
+    }    
+}    
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed Apr 25 09:35:02 2018 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/mbed_official/code/mbed/builds/994bdf8177cb
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spi1278.cpp	Wed Apr 25 09:35:02 2018 +0000
@@ -0,0 +1,375 @@
+#include <stdint.h>
+#include "mbed.h"
+#include "spi1278.h"
+extern SPI spi;
+extern DigitalOut cs; 
+extern DigitalOut rs; 
+extern Serial pc;
+
+
+uint16_t sx1278_readRegister(sx1278_t *psx1278,const uint8_t RegisterNumber)
+{
+    uint16_t result;
+    cs=0;
+    spi.write(RegisterNumber);
+   // wait(0.001);
+    result = spi.write(0xFF);
+   // wait(0.001);
+    cs=1;
+    return(result);
+}
+    
+void sx1278_writeRegister(sx1278_t *psx1278,const uint8_t RegisterNumber, uint8_t Value)
+{
+    //uint16_t result;
+    cs=0;
+    spi.write(RegisterNumber | 0x80);//set MSB to to do a write. "1" for write, "0" for read.
+    spi.write(Value);
+    cs=1;
+}
+
+//Initialize the transceiver
+void sx1278_init(sx1278_t *psx1278) 
+{        
+    //Reset the transceiver
+    rs=0;
+    wait(0.1);
+    rs=1;
+    wait(0.1);
+    //put in sleep mode
+    sx1278_sleep(psx1278);
+    //Switch to LoRa mode
+    sx1278_writeRegister(psx1278,REG_OP_MODE, MODE_LONG_RANGE_MODE);
+    //set frequency
+    sx1278_setFrequency(psx1278,psx1278->_frequency);
+    psx1278->_packetIndex = 0;
+    psx1278->_implicitHeaderMode = 0;
+    //set base addresses
+    sx1278_writeRegister(psx1278,REG_FIFO_TX_BASE_ADDR, 0);
+    sx1278_writeRegister(psx1278,REG_FIFO_RX_BASE_ADDR, 0);
+    //set LNA boost
+    sx1278_writeRegister(psx1278,REG_LNA, sx1278_readRegister(psx1278,REG_LNA) | 0x03);
+    //set auto AGC
+    sx1278_writeRegister(psx1278,REG_MODEM_CONFIG_3, 0x04);
+    //set output power to 17 dBm
+    sx1278_setTxPower(psx1278,17,1);
+    //put in standby mode
+    sx1278_idle(psx1278);    
+}
+
+void sx1278_displayRegisters(sx1278_t *psx1278)
+{
+    uint8_t RegNum=0;
+    pc.printf("--SX1278 Register contents--\r\n");
+    pc.printf(" RegNum      | Value        \r\n");    
+    for (RegNum = 0; RegNum <= 0x70; RegNum++)
+    {
+        pc.printf("  %02X         |",RegNum);
+        pc.printf("  %02X         \r\n",sx1278_readRegister(psx1278,RegNum));
+    }    
+    pc.printf("----------------------------\r\n");
+}
+
+void sx1278_end(sx1278_t *psx1278)
+{
+  //put in sleep mode
+  sx1278_sleep(psx1278);  
+}
+
+int sx1278_beginPacket(sx1278_t *psx1278,int implicitHeader)
+{
+  //put in standby mode
+  sx1278_idle(psx1278);
+  
+  if (implicitHeader) {
+    sx1278_implicitHeaderMode(psx1278);
+  } 
+  else {
+    sx1278_explicitHeaderMode(psx1278);
+  }
+  //reset FIFO address and paload length
+  sx1278_writeRegister(psx1278,REG_FIFO_ADDR_PTR, 0);
+  sx1278_writeRegister(psx1278,REG_PAYLOAD_LENGTH, 0);
+  
+  return 1;
+}
+
+int sx1278_endPacket(sx1278_t *psx1278)
+{
+  //put in TX mode
+  sx1278_writeRegister(psx1278,REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_TX);
+  //wait for TX done
+  while((sx1278_readRegister(psx1278,REG_IRQ_FLAGS) & IRQ_TX_DONE_MASK) == 0);
+  //clear IRQ's
+  sx1278_writeRegister(psx1278,REG_IRQ_FLAGS, IRQ_TX_DONE_MASK);
+
+  return 1;
+}
+
+int sx1278_parsePacket(sx1278_t *psx1278,int size)
+{
+  int packetLength = 0;
+  int irqFlags = sx1278_readRegister(psx1278,REG_IRQ_FLAGS);
+
+  if (size > 0) {
+    sx1278_implicitHeaderMode(psx1278);
+    sx1278_writeRegister(psx1278,REG_PAYLOAD_LENGTH, size & 0xff);
+  }
+  else {
+    sx1278_explicitHeaderMode(psx1278);
+  }
+
+  //clear IRQ's
+  sx1278_writeRegister(psx1278,REG_IRQ_FLAGS, irqFlags);
+
+  if ((irqFlags & IRQ_RX_DONE_MASK) && (irqFlags & IRQ_PAYLOAD_CRC_ERROR_MASK) == 0) {
+    //received a packet
+    psx1278->_packetIndex = 0;
+    //read packet length
+    if (psx1278->_implicitHeaderMode) {
+      packetLength = sx1278_readRegister(psx1278,REG_PAYLOAD_LENGTH);
+    } 
+    else {
+      packetLength = sx1278_readRegister(psx1278,REG_RX_NB_BYTES);
+    }
+    //set FIFO address to current RX address
+    sx1278_writeRegister(psx1278,REG_FIFO_ADDR_PTR, sx1278_readRegister(psx1278,REG_FIFO_RX_CURRENT_ADDR));
+    //put in standby mode
+    sx1278_idle(psx1278);
+  } 
+  else if (sx1278_readRegister(psx1278,REG_OP_MODE) != (MODE_LONG_RANGE_MODE | MODE_RX_SINGLE)) {
+    //not currently in RX mode
+    //reset FIFO address
+    sx1278_writeRegister(psx1278,REG_FIFO_ADDR_PTR, 0);
+    //put in single RX mode
+    sx1278_writeRegister(psx1278,REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_SINGLE);
+  }
+  return packetLength;
+}
+
+int sx1278_packetRssi(sx1278_t *psx1278)
+{
+  return (sx1278_readRegister(psx1278,REG_PKT_RSSI_VALUE) - (psx1278->_frequency < 868E6 ? 164 : 157));  
+}
+
+float sx1278_packetSnr(sx1278_t *psx1278)
+{
+  return ((int8_t)sx1278_readRegister(psx1278,REG_PKT_SNR_VALUE)) * 0.25;
+}
+
+size_t sx1278_write(sx1278_t *psx1278,const uint8_t *buffer, size_t size)
+{
+  int currentLength = sx1278_readRegister(psx1278,REG_PAYLOAD_LENGTH);
+  // check size
+  if ((currentLength + size) > MAX_PKT_LENGTH) {
+    size = MAX_PKT_LENGTH - currentLength;
+  }
+  // write data
+
+  for (size_t i = 0; i < size; i++) {
+    sx1278_writeRegister(psx1278,REG_FIFO, buffer[i]);
+  }
+  // update length
+  sx1278_writeRegister(psx1278,REG_PAYLOAD_LENGTH, currentLength + size);
+
+  return size;
+}
+
+int sx1278_available(sx1278_t *psx1278)
+{
+  return (sx1278_readRegister(psx1278,REG_RX_NB_BYTES) - psx1278->_packetIndex);
+}
+
+int sx1278_read(sx1278_t *psx1278)
+{
+  if (!sx1278_available(psx1278)) {
+    
+    return -1;
+  }
+
+  psx1278->_packetIndex++;
+
+  return sx1278_readRegister(psx1278,REG_FIFO);
+}
+
+int sx1278_peek(sx1278_t *psx1278)
+{
+  if (!sx1278_available(psx1278)) {
+    
+    return -1;
+  }
+
+  // store current FIFO address
+  int currentAddress = sx1278_readRegister(psx1278,REG_FIFO_ADDR_PTR);
+  // read
+  uint8_t b = sx1278_readRegister(psx1278,REG_FIFO);
+  // restore FIFO address
+  sx1278_writeRegister(psx1278,REG_FIFO_ADDR_PTR, currentAddress);
+
+  return b;
+}
+
+void sx1278_flush(sx1278_t *psx1278)
+{
+
+}
+
+void sx1278_receive(sx1278_t *psx1278,int size)
+{
+  if (size > 0) {
+    sx1278_implicitHeaderMode(psx1278);
+    sx1278_writeRegister(psx1278,REG_PAYLOAD_LENGTH, size & 0xff);
+  } 
+  else {
+    sx1278_explicitHeaderMode(psx1278);
+  }
+  sx1278_writeRegister(psx1278,REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_CONTINUOUS);
+}
+
+void sx1278_idle(sx1278_t *psx1278)
+{
+  sx1278_writeRegister(psx1278,REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_STDBY);
+}
+
+void sx1278_sleep(sx1278_t *psx1278)
+{
+  sx1278_writeRegister(psx1278,REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_SLEEP);
+}
+
+void sx1278_setTxPower(sx1278_t *psx1278,int level, int outputPin)
+{
+  if (PA_OUTPUT_RFO_PIN == outputPin) {
+    // RFO
+    if (level < 0) {
+      level = 0;
+    } 
+    else if (level > 14) {
+      level = 14;
+    }
+    sx1278_writeRegister(psx1278,REG_PA_CONFIG, 0x70 | level);
+  } 
+  else {
+    // PA BOOST
+    if (level < 2) {
+      level = 2;
+    } 
+    else if (level > 17) {
+      level = 17;
+    }
+    sx1278_writeRegister(psx1278,REG_PA_CONFIG, PA_BOOST | (level - 2));
+  }
+}
+
+void sx1278_setFrequency(sx1278_t *psx1278,long frequency)
+{
+  psx1278->_frequency = frequency;
+  uint64_t frf = ((uint64_t)frequency << 19) / 32000000;
+  sx1278_writeRegister(psx1278,REG_FRF_MSB, (uint8_t)(frf >> 16));
+  sx1278_writeRegister(psx1278,REG_FRF_MID, (uint8_t)(frf >> 8));
+  sx1278_writeRegister(psx1278,REG_FRF_LSB, (uint8_t)(frf >> 0));
+}
+
+void sx1278_setSpreadingFactor(sx1278_t *psx1278,int sf)
+{
+  if (sf < 6) {
+    sf = 6;
+  } 
+  else if (sf > 12) {
+    sf = 12;
+  }
+  if (sf == 6) {
+    sx1278_writeRegister(psx1278,REG_DETECTION_OPTIMIZE, 0xc5);
+    sx1278_writeRegister(psx1278,REG_DETECTION_THRESHOLD, 0x0c);
+  } 
+  else {
+    sx1278_writeRegister(psx1278,REG_DETECTION_OPTIMIZE, 0xc3);
+    sx1278_writeRegister(psx1278,REG_DETECTION_THRESHOLD, 0x0a);
+  }
+  sx1278_writeRegister(psx1278,REG_MODEM_CONFIG_2, (sx1278_readRegister(psx1278,REG_MODEM_CONFIG_2) & 0x0f) | ((sf << 4) & 0xf0));
+}
+void sx1278_setSignalBandwidth(sx1278_t *psx1278,long sbw)
+{
+  int bw;
+  if (sbw <= 7.8E3) {
+    bw = 0;
+  } 
+  else if (sbw <= 10.4E3) {
+    bw = 1;
+  } 
+  else if (sbw <= 15.6E3) {
+    bw = 2;
+  } 
+  else if (sbw <= 20.8E3) {
+    bw = 3;
+  } 
+  else if (sbw <= 31.25E3) {
+    bw = 4;
+  } 
+  else if (sbw <= 41.7E3) {
+    bw = 5;
+  } 
+  else if (sbw <= 62.5E3) {
+    bw = 6;
+  } 
+  else if (sbw <= 125E3) {
+    bw = 7;
+  } 
+  else if (sbw <= 250E3) {
+    bw = 8;
+  } 
+  else /*if (sbw <= 250E3)*/ {
+    bw = 9;
+  }
+  sx1278_writeRegister(psx1278,REG_MODEM_CONFIG_1, (sx1278_readRegister(psx1278,REG_MODEM_CONFIG_1) & 0x0f) | (bw << 4));
+}
+
+void sx1278_setCodingRate4(sx1278_t *psx1278,int denominator)
+{
+  if (denominator < 5) {
+    denominator = 5;
+  } 
+  else if (denominator > 8) {
+    denominator = 8;
+  }
+
+  int cr = denominator - 4;
+  sx1278_writeRegister(psx1278,REG_MODEM_CONFIG_1, (sx1278_readRegister(psx1278,REG_MODEM_CONFIG_1) & 0xf1) | (cr << 1));
+}
+
+void sx1278_setPreambleLength(sx1278_t *psx1278,long length)
+{
+  sx1278_writeRegister(psx1278,REG_PREAMBLE_MSB, (uint8_t)(length >> 8));
+  sx1278_writeRegister(psx1278,REG_PREAMBLE_LSB, (uint8_t)(length >> 0));
+}
+
+void sx1278_setSyncWord(sx1278_t *psx1278,int sw)
+{
+  sx1278_writeRegister(psx1278,REG_SYNC_WORD, sw);
+}
+
+void sx1278_enableCrc(sx1278_t *psx1278)
+{
+  sx1278_writeRegister(psx1278,REG_MODEM_CONFIG_2, sx1278_readRegister(psx1278,REG_MODEM_CONFIG_2) | 0x04);
+}
+
+void sx1278_disableCrc(sx1278_t *psx1278)
+{
+  sx1278_writeRegister(psx1278,REG_MODEM_CONFIG_2, sx1278_readRegister(psx1278,REG_MODEM_CONFIG_2) & 0xfb);
+}
+
+uint8_t sx1278_random(sx1278_t *psx1278)
+{
+  return sx1278_readRegister(psx1278,REG_RSSI_WIDEBAND);
+}
+
+void sx1278_explicitHeaderMode(sx1278_t *psx1278)
+{
+  psx1278->_implicitHeaderMode = 0;
+  sx1278_writeRegister(psx1278, REG_MODEM_CONFIG_1, sx1278_readRegister(psx1278,REG_MODEM_CONFIG_1) & 0xfe);
+}
+
+void sx1278_implicitHeaderMode(sx1278_t *psx1278)
+{
+  psx1278->_implicitHeaderMode = 1;
+  sx1278_writeRegister(psx1278,REG_MODEM_CONFIG_1, sx1278_readRegister(psx1278,REG_MODEM_CONFIG_1) | 0x01);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spi1278.h	Wed Apr 25 09:35:02 2018 +0000
@@ -0,0 +1,89 @@
+#include <stdint.h>
+
+
+typedef struct {
+
+    uint32_t _implicitHeaderMode;
+    uint32_t _frequency;
+    uint32_t _packetIndex;
+} 
+ 
+sx1278_t;
+void sx1278_init(sx1278_t *psx1278);
+void sx1278_displayRegisters(sx1278_t *psx1278);
+void sx1278_writeRegister(sx1278_t *psx1278, const uint8_t RegisterNumber, uint8_t Value);
+uint16_t sx1278_readRegister(sx1278_t *psx1278, const uint8_t RegisterNumber);
+int sx1278_beginPacket(sx1278_t *psx1278,int implicitHeader);
+int sx1278_endPacket(sx1278_t *psx1278);
+int sx1278_parsePacket(sx1278_t *psx1278,int size);
+int sx1278_packetRssi(sx1278_t *psx1278);
+float sx1278_packetSnr(sx1278_t *psx1278);
+size_t sx1278_write(sx1278_t *psx1278,const uint8_t *buffer, size_t size);
+int sx1278_available(sx1278_t *psx1278);
+int sx1278_read(sx1278_t *psx1278);
+int sx1278_peek(sx1278_t *psx1278);
+void sx1278_flush(sx1278_t *psx1278);
+void sx1278_receive(sx1278_t *psx1278,int size);
+void sx1278_idle(sx1278_t *psx1278);
+void sx1278_sleep(sx1278_t *psx1278);
+void sx1278_setTxPower(sx1278_t *psx1278,int level, int outputPin);
+void sx1278_setFrequency(sx1278_t *psx1278,long frequency);
+void sx1278_setSpreadingFactor(sx1278_t *psx1278,int sf);
+void sx1278_setSignalBandwidth(sx1278_t *psx1278,long sbw);
+void sx1278_setCodingRate4(sx1278_t *psx1278,int denominator);
+void sx1278_setPreambleLength(sx1278_t *psx1278,long length);
+void sx1278_setSyncWord(sx1278_t *psx1278,int sw);
+void sx1278_enableCrc(sx1278_t *psx1278);
+void sx1278_disableCrc(sx1278_t *psx1278);
+uint8_t sx1278_random(sx1278_t *psx1278);
+void sx1278_implicitHeaderMode(sx1278_t *psx1278);
+void sx1278_explicitHeaderMode(sx1278_t *psx1278);
+
+//registers
+#define REG_FIFO                 0x00
+#define REG_OP_MODE              0x01
+#define REG_FRF_MSB              0x06
+#define REG_FRF_MID              0x07
+#define REG_FRF_LSB              0x08
+#define REG_PA_CONFIG            0x09
+#define REG_LNA                  0x0c
+#define REG_FIFO_ADDR_PTR        0x0d
+#define REG_FIFO_TX_BASE_ADDR    0x0e
+#define REG_FIFO_RX_BASE_ADDR    0x0f
+#define REG_FIFO_RX_CURRENT_ADDR 0x10
+#define REG_IRQ_FLAGS            0x12
+#define REG_RX_NB_BYTES          0x13
+#define REG_PKT_SNR_VALUE        0x19
+#define REG_PKT_RSSI_VALUE       0x1a
+#define REG_MODEM_CONFIG_1       0x1d
+#define REG_MODEM_CONFIG_2       0x1e
+#define REG_PREAMBLE_MSB         0x20
+#define REG_PREAMBLE_LSB         0x21
+#define REG_PAYLOAD_LENGTH       0x22
+#define REG_MODEM_CONFIG_3       0x26
+#define REG_RSSI_WIDEBAND        0x2c
+#define REG_DETECTION_OPTIMIZE   0x31
+#define REG_DETECTION_THRESHOLD  0x37
+#define REG_SYNC_WORD            0x39
+#define REG_DIO_MAPPING_1        0x40
+#define REG_VERSION              0x42
+
+
+//modes
+#define MODE_LONG_RANGE_MODE     0x80
+#define MODE_SLEEP               0x00
+#define MODE_STDBY               0x01
+#define MODE_TX                  0x03
+#define MODE_RX_CONTINUOUS       0x05
+#define MODE_RX_SINGLE           0x06
+
+//IRQ masks
+#define IRQ_TX_DONE_MASK           0x08
+#define IRQ_PAYLOAD_CRC_ERROR_MASK 0x20
+#define IRQ_RX_DONE_MASK           0x40
+#define MAX_PKT_LENGTH           255
+
+//PA config
+#define PA_BOOST                 0x80
+#define PA_OUTPUT_RFO_PIN      0
+#define PA_OUTPUT_PA_BOOST_PIN 1