standalone sx1276 demo program

Dependencies:   SX1276Lib mbed

Fork of SX1276_GPS by CaryCoders

utilities.cpp

Committer:
ftagius
Date:
2015-09-03
Revision:
33:319cbac3b6eb
Parent:
32:a2472bbe7c92

File content as of revision 33:319cbac3b6eb:

#include "mbed.h"
#include "sx1276-hal.h"
#include "main.h"
#include "debug.h"
#include "serial_api.h"

#ifndef STANDALONE
void gps_setup(void)
{
    printf("setting up gps\r\n");
    gpsd.setBaud(9600);
    gpsd.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); 
    gpsd.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
    gpsd.sendCommand(PGCMD_NOANTENNA);
    gpsd.day=01;
    gpsd.month=01;
    gpsd.year=15;
    gpsd.hour=1;
    gpsd.minute=1;
    gpsd.seconds=1;
}    
#endif
int get_kbd_str2(char* buf, int size)
{
    char c;
    int i;
    static int prev_len;
    
    for (i = 0;;) {
        if (pc.readable()) {
            c = pc.getc();
            if (c == 8 && i > 0) {
                pc.putc(8);
                pc.putc(' ');
                pc.putc(8);
                i--;
            } else if (c == '\r') {
                if (i == 0) {
                    if (app == APP_CHAT)
                        return 0;
                    else
                        return prev_len; // repeat previous
                } else {
                    buf[i] = 0; // null terminate
                    prev_len = i;
                    return i;
                }
            } else if (c == 3) {
                // ctrl-C abort
                return -1;
            } else if (i < size) {
                buf[i++] = c;
                pc.putc(c);
            }
        }  else {
            if (app == APP_PING)
                ping_pong();
            if (app == APP_HELLO)
                hello();
#ifndef STANDALONE
            if (app == APP_GPS)
                check_gps();    
#endif          
            #if 1    
            if (app == APP_CHAT)
            {
                // printf("utility call to console chat\r\n");
                check_rx_chat();    
            }
            #endif
        }
    } // ...for()
}

int get_kbd_str(char* buf, int size)
{
    char c;
    int i;
    static int prev_len;
    
    for (i = 0;;) {
        if (pc.readable()) {
            c = pc.getc();
            if (c == 8 && i > 0) {
                pc.putc(8);
                pc.putc(' ');
                pc.putc(8);
                i--;
            } else if (c == '\r') {
                if (i == 0) {
                    if (app == APP_CHAT)
                        return 0;
                    else
                        return prev_len; // repeat previous
                } else {
                    buf[i] = 0; // null terminate
                    prev_len = i;
                    return i;
                }
            } else if (c == 3) {
                {
                // ctrl-C abort
                //printf("ctrl c\r\n");
                app = APP_CONSOLE;
                return -1;
                }
            } else if (i < size) {
                buf[i++] = c;
                pc.putc(c);
            }
        }  
        
        else {
#if 0            
            return 1;
#else            
            if (app == APP_PING)
                ping_pong();
            if (app == APP_HELLO)
            {
#ifndef STANDALONE   
                    check_gps();
#endif              
                    hello();
     
            }                
#ifndef STANDALONE
            if (app == APP_GPS)
                check_gps();    
#endif
            #if 1    
            if (app == APP_CHAT)
            {
                // printf("utility call to console chat\r\n");
                check_rx_chat();    
            }
            #endif
            #endif
        }

    } // ...for()
}
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" );
}

  
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 OnCadDone( bool activity )
{
    //Radio.Sleep();
    State = CAD;
    if (activity)
    {
    debug_if( DEBUG_MESSAGE, "> OnCadDone\n\r" );
    printf("on cad done\r\n");
    Radio.StartCad();
    }
    else
    {
        // printf("false\r\n");
        Radio.StartCad();
    }
}

#ifndef STANDALONE
void find_distance()
{
    //float dist = 0;
    float lat2 = 0;
    float lon2 = 0;
    float lat1 = 0;
    float lon1 = 0;
    float dLat = 0;
    float dLon = 0;
    float c = 0;
    float a = 0;
    float d = 0;
      
    distance = 0;
 
    if (gpsd.lat_deg == 0.0)
    {
        distance = -1;
        return;
    }
    if (gpsd.lon_deg == 0.0)
    {
        distance = -1;
        return;
    }
    
    lat1 = r_latitude_last;
    lon1 = r_longitude_last;
        
    lat2 = gpsd.lat_deg;
    lon2 = gpsd.lon_deg;
    //Calculate Distance
    dLat = (lat2-lat1)*(PI/180);
    dLon = (lon2-lon1)*(PI/180);
    a = sin(dLat/2) * sin(dLat/2) +
    sin(dLon/2) * sin(dLon/2) * cos(lat1*(PI/180)) * cos(lat2*(PI/180));
    c = 2 * atan2(sqrt(a), sqrt(1-a));
    d = 6371000 * c;
 
    //GPS is only precise to 5 meters, so throw out bad data
    if ( d <= 5) {
       d = 0;
    }
    distance = distance + d;
#if 0    
    if (distance > 10000)
    {
       printf("distance: %f\r\n", distance);
       printf("lat1=%f lon1=%f lat2=%f lon2=%f\r\n",lat1,lon1,lat2,lon2);
    }
#endif    
   
}
 
int check_gps(void)
{
  
        char c;
        int debug=0;
        c = gpsd.read();   //queries the GPS
        if (debug)
        {
            if (c) { 
                printf("%c", c);  //this line will echo the GPS data if not paused
                return 1;
                
            }
        }
        
        //check if we recieved a new message from GPS, if so, attempt to parse it,
        if ( gpsd.newNMEAreceived() ) {
              //printf("nmea received \r\n");
              if (r_latitude_last != 0)
              {
                    find_distance();
                    //printf("distance is %f\r\n",distance);
                    if (distance < 50000 )
                    {
                        if (distance >= 0)
                        {
                            cLCD.setCursor(0,1);
                            cLCD.printf("d:%0.1fm per:%d      ", distance,per);
                        }

                    }
                    //printf("distance = %f, %f\r\n",distance, r_latitude_last);
               }
               else
               {
                    cLCD.setCursor(0,1);
                    if (gpsd.lat_deg != 0)
                        cLCD.printf("%0.4f %0.4f", gpsd.lat_deg, gpsd.lon_deg);
                    else
                        cLCD.printf("No GPS. per:%d      ",per);
                }
               
 
   
            if ( !gpsd.parse(gpsd.lastNMEA()) )  
            {
               // radfta led = !led;   
               #if 0
               if (gpsd.lat_deg != 0)
               {
                    cLCD.setCursor(0,1);
                    cLCD.printf("d:Nx per:%d      ", per);
                    cLCD.printf("%0.4f %0.4f", gpsd.lat_deg, gpsd.lon_deg);
               }
               #endif


              
               return 0;
            }
            else
            {
             // printf("GPS  %02d/%02d/20%02d_%02d:%02d:%02d (UTC)\r\n",gpsd.month,gpsd.day,gpsd.year,gpsd.hour,gpsd.minute,gpsd.seconds);
               return 1;
            }
               
        } 
        else
        {     
           //printf("GPS  %02d/%02d/20%02d_%02d:%02d:%02d (UTC)\r\n",gpsd.month,gpsd.day,gpsd.year,gpsd.hour,gpsd.minute,gpsd.seconds);
           return 0;   
        }
   
}
#endif