Wireless interface using LoRa technology

Dependencies:   AlohaTransceiver RingBuffer SX1276Lib_inAir SerialInterfaceProtocol mbed L3PDU

main.cpp

Committer:
rba90
Date:
2016-07-17
Revision:
4:9151697dfa70
Parent:
3:7bb50ee42cba
Child:
8:e30610bf6f79

File content as of revision 4:9151697dfa70:

#include "mbed.h"
#include "AlohaTransceiver.h"
#include "buffer.h"
#include "SerialInterfaceProtocol.h"
#include "AlohaFrame.h"

Serial pc(USBTX, USBRX);

// sip uses two buffer queues
CircularBuffer<uint8_t> SerialInputBuffer;
CircularBuffer<uint8_t> SerialOutputBuffer;
SerialInterfaceProtocol SIP(&SerialInputBuffer, &SerialOutputBuffer);

// aloha transceiver
AlohaTransceiver aloha;
AlohaFrame txFrame;
Timer timer;
InterruptIn button(USER_BUTTON);

void serialInterruptHandler() {
    // Note: you need to actually read from the serial to clear the RX interrupt
    int c = pc.getc();
    
    // add to buffer
    if (SerialInputBuffer.isLocked())
    {
        printf("Mutex Locked\r\n");
    }
    else
    {
        SerialInputBuffer.enqueue((uint8_t) c);   
    }
}

int toggleChecksum(uint8_t *payload, uint8_t payload_length, uint8_t *response, uint8_t *response_length)
{
    // one payload
    if (payload_length != 1)
    {
        sprintf((char *) response, "Wrong Payload Length\r\n");
        *response_length = 22;
        return 1;
    } 
    
    if ((bool) payload[0])
    {
        SIP.enableChecksum();
    }
    else
    {
        SIP.disableChecksum();
    }
    
    return 0;
}

int sendMessage(uint8_t *payload, uint8_t payload_length, uint8_t *response, uint8_t *response_length)
{
    static uint8_t seqid = 0;
    
    // prepare for the frame
    txFrame.setType(AlohaFrame::Aloha_Data);
    txFrame.setPayloadLength(0x0);
    txFrame.setSourceAddress(0x1);
    txFrame.setDestinationAddress(0x2);
    txFrame.setFullMessageFlag(0x1);
    txFrame.setSequenceID(seqid);
    txFrame.generateCrc();
    
    
    uint8_t buffer[20];
    memset(buffer, 0x0, sizeof(buffer));
    txFrame.serialize(buffer);
    
    aloha.send(buffer, 20);
    
    seqid += 1;
    
    // start the timer to measure round trip time
    timer.reset();
    timer.start();
    
    return 0;   
}

/*
 * Format: 
 * <        :start flag
 * 02       :command
 * xx       :length
 * xx:      :00: get, 01: set
 * xx       :index for parameters
 * ...
 * ff       :checksum
 * >        :end flag
 */
int configureRadio(uint8_t *payload, uint8_t payload_length, uint8_t *response, uint8_t *response_length)
{
    // read settings from radio
#if USE_MODEM_LORA == 1
    AlohaTransceiver::LoRaSettings_t *settings = aloha.getSettings();
#elif USE_MODEM_FSK == 1
    AlohaTransceiver::FskSettings_t *settings = aloha.getSettings();
#else
    #error "Please define a modem in the compiler options."
#endif

    if (payload_length < 2)
    {
        sprintf((char *) response, "Wrong Payload Length\r\n");
        *response_length = 22;
        return 1;
    }
    
    // true is set, false is get
    bool isSet = (bool) payload[0];
    uint8_t idx = payload[1];
    
    switch(idx)
    {
        case 0x00: // Power
        {
            if (isSet)
            {
                int8_t Power = (int8_t) payload[2];
                settings->Power = Power;
                
                return 0;
            }
            else
            {
                response[0] = (uint8_t) settings->Power;
                *response_length = 1;

                return 0;
            }
        }
        
        case 0x01: // Bandwidth
        {
            if (isSet)
            {
                uint32_t Bandwidth = (payload[4]) | 
                                     (payload[3] << 8) |
                                     (payload[2] << 16) | 
                                     (payload[1] << 24);
                settings->Bandwidth = Bandwidth;
                
                return 0;
            }
            else
            {
                response[3] = (uint8_t) (settings->Bandwidth);
                response[2] = (uint8_t) (settings->Bandwidth >> 8);
                response[1] = (uint8_t) (settings->Bandwidth >> 16);
                response[0] = (uint8_t) (settings->Bandwidth >> 24);
                *response_length = 4;
                
                return 0;
            }
            
        }
        
        case 0x02: // Daterate
        {
            if (isSet)
            {
                uint32_t Datarate = (payload[4]) | 
                                    (payload[3] << 8) |
                                    (payload[2] << 16) | 
                                    (payload[1] << 24);
                settings->Datarate = Datarate;
                
                return 0;
            }
            else
            {
                response[3] = (uint8_t) (settings->Datarate);
                response[2] = (uint8_t) (settings->Datarate >> 8);
                response[1] = (uint8_t) (settings->Datarate >> 16);
                response[0] = (uint8_t) (settings->Datarate >> 24);
                *response_length = 4;
                
                return 0;
            }
        }
        
        case 0x03: // Coderate
        {
            if (isSet)
            {
                uint8_t Coderate = payload[1];
                settings->Coderate = Coderate;
                
                return 0;
            }
            else
            {
                response[0] = (uint8_t) settings->Coderate;
                *response_length = 1;

                return 0;
            }
        }
        
        default:
        {
            break;
        }
    }
        
    
    return 0;
}

void AlohaDataHandler(AlohaFrame *frame)
{
    // stop the timer to measure round trip time
    timer.stop();
    
    printf("-----------------------------------------\r\n");
    printf(">Received Frame\r\n");
    printf(">    Type: 0x%x, PayloadLength: 0x%x\r\n", frame->getType(), frame->getPayloadLength());
    printf(">    SrcAddr: 0x%x, DestAddr: 0x%x\r\n", frame->getSourceAddress(), frame->getDestinationAddress());
    printf(">    FMF: 0x%x, SequenceID: 0x%x\r\n", frame->getFullMessageFlag(), frame->getSequenceID());
    for (uint8_t i = 0; i < frame->getPayloadLength(); i++)
    {
        printf(">    Payload[%d]: 0x%x\r\n", i, frame->getPayload(i));
    }
    printf(">    CRC: 0x%x\r\n", frame->getCrc());
    
    // decode payload (range test only)
    int8_t snr = (int8_t) frame->getPayload(0);
    
    uint16_t rssi_h = frame->getPayload(1);
    uint8_t rssi_l = frame->getPayload(2);
    int16_t rssi = (int16_t) (rssi_h << 8 | rssi_l);
    
    
    printf(">About this transmission:\r\n");
    printf(">   Base Station:: Rssi: %d, Snr: %d\r\n", rssi, snr);
    printf(">   Terminal::     Rssi: %d, Snr: %d\r\n", aloha.getRssi(), aloha.getSnr());
    printf(">   Round trip time: %d ms\r\n", timer.read_ms());
    printf("-----------------------------------------\r\n");
}

void automaticPacketTransmit()
{
    SerialInputBuffer.enqueue((uint8_t) '<');
    SerialInputBuffer.enqueue((uint8_t) '0');
    SerialInputBuffer.enqueue((uint8_t) '1');
    SerialInputBuffer.enqueue((uint8_t) '0');
    SerialInputBuffer.enqueue((uint8_t) '0');
    SerialInputBuffer.enqueue((uint8_t) 'f');
    SerialInputBuffer.enqueue((uint8_t) 'f');
    SerialInputBuffer.enqueue((uint8_t) '>');
}


int main() {
    // initialize radio module
    aloha.boardInit();
    aloha.updateSettings();
    aloha.enable();
    
    // attach serial interrupt handler
    pc.attach(&serialInterruptHandler);
    
    // register callback functions for SIP
    SIP.registerCommand(0x00, toggleChecksum);
    SIP.registerCommand(0x01, sendMessage);
    SIP.registerCommand(0x02, configureRadio);
    
    // register callback functions for aloha transceiver
    aloha.registerType(AlohaFrame::Aloha_Data, AlohaDataHandler);

    // configure button interrupt
    button.fall(automaticPacketTransmit);
    
    while(1) {
        SIP.poll();
        aloha.poll();
        
        while (SerialOutputBuffer.getCounter() > 0)
        {
            uint8_t ch;
            ch = SerialOutputBuffer.dequeue();
            pc.putc(ch);
        }
    }
}