standalone sx1276 demo program

Dependencies:   SX1276Lib mbed

Fork of SX1276_GPS by CaryCoders

main.cpp

Committer:
ftagius
Date:
2015-07-14
Revision:
31:2c813f321db7
Parent:
29:0ea07cc7124b
Child:
32:a2472bbe7c92

File content as of revision 31:2c813f321db7:

#include "mbed.h"
#include "lcdadafruit.h"
//radfta #include "keyreaderadafruit.h"
//radfta #include "keyreadernull.h"
// #include "RTclock.h"
//#include "DateModule.h"
//#include "TempModule.h"
//#include "TimeModule.h"
//#include "TitleModule.h"
//#include "SyncModule.h"
//#include "GPSModule.h"
//#include "LatitudeModule.h"
//#include "RadioModule.h"
//#include "MenuManager.h"
#include "sx1276-hal.h"
#include "GPS.h"
#include "main.h"
#include "debug.h"
//#include "vt100.h"
#include "serial_api.h"


/* Set this flag to '1' to display debug messages on the console */
#define DEBUG_MESSAGE   1
#define USE_MODEM_LORA  1

//#define RF_FREQUENCY                                    868000000 // Hz
//#define RF_FREQUENCY                                    880030000 
#define RF_FREQUENCY                                    915000000.0 // Hz
//#define RF_FREQUENCY                                    413000000.0 // Hz
#define TX_OUTPUT_POWER                                 20        // 14 dBm
#define LORA_BANDWIDTH                                  2         // [0: 125 kHz,
                                                                  //  1: 250 kHz,
                                                                  //  2: 500 kHz,
                                                                  //  3: Reserved]
// #define LORA_SPREADING_FACTOR                        7         // [SF7..SF12]
#define LORA_SPREADING_FACTOR                           12        // [SF7..SF12]
// #define LORA_CODINGRATE                              1         // [1: 4/5,
#define LORA_CODINGRATE                                 2         // [1: 4/5,
                                                                  //  2: 4/6,
                                                                  //  3: 4/7,
                                                                  //  4: 4/8]
#define LORA_PREAMBLE_LENGTH                            8         // Same for Tx and Rx
#define LORA_SYMBOL_TIMEOUT                             5         // Symbols
#define LORA_FIX_LENGTH_PAYLOAD_ON                      false
#define LORA_FHSS_ENABLED                               false  
#define LORA_NB_SYMB_HOP                                4     
#define LORA_IQ_INVERSION_ON                            false
#define LORA_CRC_ENABLED                                true

//#define BUFFER_SIZE                                     64        // Define the payload size here

#if( defined ( TARGET_KL25Z ) || defined ( TARGET_LPC11U6X ) )
DigitalOut led(LED2);
//DigitalOut led(LED_RED);
#else
DigitalOut led(LED1);
#endif
Serial pc(USBTX, USBRX);

float Frequency = RF_FREQUENCY;
int TxPower = TX_OUTPUT_POWER;
int Bandwidth = LORA_BANDWIDTH;
int SpreadingFactor = LORA_SPREADING_FACTOR;
int CodingRate = LORA_CODINGRATE;

/*
 *  Global variables declarations
 */
typedef RadioState States_t;
volatile States_t State = LOWPOWER;
// radfta vt100 ctrl;

SX1276MB1xAS Radio( OnTxDone, OnTxTimeout, OnRxDone, OnRxTimeout, OnRxError, NULL, NULL );
// for hand wired I2C cI2C(PTC9, PTC8); 
I2C cI2C(PTC9, PTC8); 
// for stacked shield I2C cI2C(PTC2, PTC1); 
//I2C cI2C(PTC2, PTC1);
LCDadafruit cLCD(cI2C);
GPS gpsd(PTE0,PTE1);
  
// for other board GPS gpsd(PTE20, PTE21);

uint8_t PingMsg[256];
uint8_t PongMsg[256];
uint8_t HelloMsg[256];
char pcbuf[PCBUF_SIZE];
uint16_t BufferSize = BUFFER_SIZE;
uint8_t BufferTx[BUFFER_SIZE];
uint8_t BufferRx[BUFFER_SIZE];
int16_t RssiValue = 0.0;
int8_t SnrValue = 0.0;
int txLen = 0;
int pkt_count = 0;
int max_pkts = 20;
int pkt_data[20];
int per = 0;
app_e app = APP_NONE;
bool isMaster = true;
bool AlwaysMaster = false;
bool AlwaysSlave = false;
bool ackRcvd = true;
bool rxTimeout = false;
bool gpsEnabled = true;
  
char* itoa(int val, int base){
    
    static char buf[32] = {0};
    
    int i = 30;
    
    for(; val && i ; --i, val /= base)
    
        buf[i] = "0123456789abcdef"[val % base];
    
    return &buf[i+1];
    
}    

unsigned int randomSeed(){
    AnalogIn randIn(A0);  // analog input for random number seed
    unsigned int rnum = 0;  // int = 4 bytes - 32 bits
    // build 32 bit random number from the 2 lower bits from 16 analog reads
    for (int i = 0; i<4;i++){
        rnum = rnum | ((randIn.read_u16() & 15) << i*4);
        wait_ms(5);
    }
    return rnum;
}

void configRxTx() {


    Radio.SetTxConfig( MODEM_LORA, TxPower, 0, Bandwidth,
                         SpreadingFactor, CodingRate,
                         LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
                         LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, 
                         LORA_IQ_INVERSION_ON, 2000000 );
    
    Radio.SetRxConfig( MODEM_LORA, Bandwidth, SpreadingFactor,
                         CodingRate, 0, LORA_PREAMBLE_LENGTH,
                         LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0,
                         LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, 
                         LORA_IQ_INVERSION_ON, true );
}

void print_bandwidth()
{
    printf("bandwidth: ");
    switch (((Radio.Read(REG_LR_MODEMCONFIG1) & 0xf0) >> 4)) {
        case 0: printf("7.8KHz "); break;
        case 1: printf("10.4KHz "); break;
        case 2: printf("15.6KHz "); break;
        case 3: printf("20.8KHz "); break;
        case 4: printf("31.25KHz "); break;
        case 5: printf("41.7KHz "); break;
        case 6: printf("62.5KHz "); break;
        case 7: printf("125KHz "); break;
        case 8: printf("250KHz "); break;
        case 9: printf("500KHz "); break;
        default: printf("%x ", Radio.Read(REG_LR_MODEMCONFIG1)); break;
    }
    //printf("\r\n");     
}

void print_cr()
{
    int cr = (Radio.Read(REG_LR_MODEMCONFIG1) & 0x0f)>>1;
    printf("coding rate: ");
    switch (cr)
    {
        case 1:
            printf("4/5");
            break;
        case 2:
            printf("4/6");
            break;
        case 3:
            printf("4/7");
            break;     
        case 4:
            printf("4/8");
            break;                   
        default:
            printf("unknown");
            break;
    
    }
    printf(" ");
}

void print_power()
{
    uint8_t paConfig = 0;
    uint8_t paDac = 0;
     
    paConfig = Radio.Read( REG_PACONFIG );
    paDac = Radio.Read( REG_PADAC );

    paConfig = ( paConfig & RF_PACONFIG_PASELECT_MASK ) | Radio.GetPaSelect( Radio.GetChannel()*1000000);
    paConfig = ( paConfig & RF_PACONFIG_MAX_POWER_MASK ) | 0x70;
    printf("channel = %f getpa = %x, paConfig =%x \r\n",Radio.GetChannel(), Radio.GetPaSelect((uint32_t)Radio.GetChannel()*1000000), paConfig );
    if( ( paConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST )
    {
        if( ( paDac & RF_PADAC_20DBM_ON ) == RF_PADAC_20DBM_ON )
        {
            printf("Power: %d dBm ", ( uint8_t )( ( uint16_t )( paConfig) & 0x0f  ) + 5 );
        }
        else
            printf("Power: %d dBm ", ( uint8_t )( ( uint16_t )( paConfig) &0x0f) + 2 );
    }
    else
    {
        printf("Power: %d dBm ", ( uint8_t )( ( uint16_t )( paConfig) & 0x0f ) - 1 );
    }
  
}

void print_errata()
{
    
        int seqconfig1 = (Radio.Read(REG_SEQCONFIG1));
        int timer2 = (Radio.Read(REG_TIMER2COEF));
        printf("seqconfig1 = 0x%02x\r\n", seqconfig1);
        printf("timer2coef = 0x%02x\r\n", timer2);

}
void print_status()
{

    printf("Radio version: 0x%02x Channel: %.1f MHz ", \
            Radio.Read(REG_VERSION),\
            Radio.GetChannel()\
            );
    print_power();        
    print_bandwidth(); printf("\r\n");
    printf("Spreading Factor: %d ",SpreadingFactor);
    print_cr();
    if (isMaster)
        printf("Mode: master ");
    else
        printf("Mode: slave ");
        
 
     printf("\r\n");
     print_errata();
     printf("\r\n");
 
}


void OnTxDone( void )
{
    Radio.Sleep( );
    State = TX;
    pkt_count++;

   
    //debug_if( DEBUG_MESSAGE, "> OnTxDone\r\n" );
}

void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
{
    Radio.Sleep( );
    if (pkt_count >= max_pkts)
    {
        pkt_count=0;
    } 
    
    // mark the rolling avg that a pkt has been received
    pkt_data[pkt_count]=1;
    //printf("rx done, pkt_count = %d\r\n", pkt_count);
 
    BufferSize = size;
    int i;
    for (i=0; i< BUFFER_SIZE; i++)
        BufferRx[ i ] = '\0';  // clear the buffer
 
    memcpy( BufferRx, payload, BufferSize );
    if (rssi > 100)
    {
     rssi *= -1;
    }
    RssiValue = rssi;
    SnrValue = snr;
    State = RX;
    rxTimeout = false;
    if (app == APP_PING)  
        debug_if( DEBUG_MESSAGE, "> OnRxDone size=%d rssi=%d snr=%d  \r\n", size, rssi, snr );
  
}

void OnTxTimeout( void )
{
    Radio.Sleep( );
    State = TX_TIMEOUT;
    //debug_if( DEBUG_MESSAGE, "> OnTxTimeout\r\n" );
}

void OnRxTimeout( void )
{
    Radio.Sleep( );
    int i;
    if (pkt_count >= max_pkts)
    {
        pkt_count=0;
    } 
    
    // mark the rolling avg that a pkt has not been received
    pkt_data[pkt_count]=2;
 
    for (i=0; i< BUFFER_SIZE; i++)
        BufferRx[ i ] = '\0';  // clear the buffer
    BufferSize = 0;
    State = RX_TIMEOUT;
    rxTimeout = false;
    // debug_if( DEBUG_MESSAGE, "> OnRxTimeout\r\n" );
}

void OnRxError( void )
{
    Radio.Sleep( );
    if (pkt_count >= max_pkts)
    {
        pkt_count=0;
    } 
    
    // mark the rolling avg that a pkt has not been received
    pkt_data[pkt_count]=2;
    State = RX_ERROR;
    debug_if( DEBUG_MESSAGE, "> OnRxError\r\n" );
}


int main()
{
  
    int i;
    // radfta gpsd.setBaud57600();
    pc.baud(9600);
    //pc.baud(57600);
    cI2C.frequency(400000);    // I2C can handle two different frequencies - switch to high speed if asked
    cLCD.clear();
    cLCD.home();
    cLCD.setCursor(0,0);
    cLCD.printf("   HOMER   ");
    cLCD.setCursor(0,1);
    cLCD.printf("   DOH!    ");   
 
    rxTimeout = false;
    // PTD1 (the SCK pin for the one SPI interface onboard the KL25z) is actually an output to the Blue LED. 
    // the lora shield drives SCK, which turns on the blue led.  use PTC5 instead of the default PTD1 for SCK
     
    if (RADIO_INSTALLED)
        debug( "    SX1276 Test Applications \r\n\n" );
    led = 1;  
    
    // init pkt_data array to 0
    for (i=0;i<pkt_count;i++)
        pkt_data[pkt_count]=0;

    // verify the connection with the board
    if (RADIO_INSTALLED)
    {

        while( Radio.Read( REG_VERSION ) == 0x00  )
        {
            debug( "Radio could not be detected!\r\n", NULL );
            wait( 1 );
        }
  
   
        debug_if( ( DEBUG_MESSAGE & ( Radio.DetectBoardType( ) == SX1276MB1LAS ) ) , "> Board Type: SX1276MB1LAS < \r\n" );
        debug_if( ( DEBUG_MESSAGE & ( Radio.DetectBoardType( ) == SX1276MB1MAS ) ) , "> Board Type: SX1276MB1MAS < \r\n" );
        Radio.SetChannel( Frequency ); 
        debug_if( !LORA_FHSS_ENABLED, "> LORA Mode < \r\n");
        configRxTx();
    
        //print_status();
        debug_if( DEBUG_MESSAGE, "Starting Application loop\r\n" ); 
        wait(1);
    
     // led = 0;
 
        strcat((char *)PingMsg,"PING");
        strcat((char *)PongMsg,"PONG");
        strcat((char *)HelloMsg,"HELLO_7");
         
        Radio.Rx( RX_TIMEOUT_VALUE );
        Radio.Tx( TX_TIMEOUT_VALUE );
         
        app = APP_HELLO;
    }
    else
    {
        app = APP_GPS;
        pc.printf("Starting GPS App\r\n");
    }
    
 
    while( 1 )
    {
        // wait_ms( 50 ); 
        switch (app) {
            case APP_PING:
                start_ping_pong();
                break;
            case APP_CHAT:
                console_chat();
                break;
            case APP_GPS:
                check_gps();
                break;    
            case APP_HELLO:
                start_hello();
                wait(0.11);
                break;
            case APP_CONSOLE:
                // printf("-chat-> x");
                fflush(stdout);    
                console();
                break;
            default:
                printf("unknown app %d\r\n", app);
                break;    
        } // ...switch (app)
      
    }
   
}