init

Dependencies:   aconno_I2C Lis2dh12 WatchdogTimer

MM2WayRanging.cpp

Committer:
pathfindr
Date:
2020-02-17
Revision:
58:8d4a354816b1

File content as of revision 58:8d4a354816b1:

#include "MM2WayRanging.h"
#include "NRFuart.h"


MM2WayRanging::MM2WayRanging(DW1000& DW) : dw(DW) {
    isBeacon = true;
    overflow = false;
    address = 0;
    
    LocalTimer.start();
    dw.startRX();   
}


bool MM2WayRanging::waitForFrameRX(float time_before) {
    bool frameReceived = false;
    while(!frameReceived && (LocalTimer.read() < time_before + 0.02f)) {
        frameReceived = dw.hasReceivedFrame();
    }; // wait for succeeding or timeout
    if (frameReceived) {
        //debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "Frame Received\n");debug_exe();
        callbackRX();
        dw.clearReceivedFlag();
    } else {
        //debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "Receive Timeout\n");debug_exe();
    }
    return frameReceived;
}


bool MM2WayRanging::waitForFrameTX(float time_before) {
    bool frameSent = false;
    while(!frameSent && (LocalTimer.read() < time_before + 0.02f)) {
        frameSent = dw.hasSentFrame();
    }; // wait for succeeding or timeout
    if (frameSent) {
        //debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "Frame Sent\n");debug_exe();
        callbackTX();
        dw.clearSentFlag();
    } else {
        //debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "Send Timeout\n");debug_exe();
    }
    return frameSent;
}

 

void MM2WayRanging::callbackRX() {
    dw.readRegister(DW1000_RX_BUFFER, 0, (uint8_t*)&receivedFrame, dw.getFramelength());
    
    //MESSAGES ADDRESSED FOR ALL DETECTORS
    if (receivedFrame.destination == 0) {  
        switch (receivedFrame.type) {
            case BEACON_READY:
                anchor_to_beacon_Send(receivedFrame.source);
                //TODO - WE COULD ALSO TIME THIS FRAME AND THEN DIVIDE BY THREE TO GET MORE ACCURACY?
                break;
            default : break;
        }
    }
    
    //MESSAGES ADDRESSED FOR ME
    if (receivedFrame.destination == address) 
        switch (receivedFrame.type) {
            case ANCHOR_TO_BEACON_PING:
                RxTimestamp = dw.getRXTimestamp();
                beacon_to_anchor_response_Send(receivedFrame.source, RxTimestamp);
                break;
            case BEACON_TO_ANCHOR_RESPONSE:
                rangingRxTimestamp[receivedFrame.destination] = dw.getRXTimestamp();
                //Calulate time/distance
                rangingTOF[receivedFrame.source] = (rangingRxTimestamp[receivedFrame.source] - rangingTxTimestamp[receivedFrame.source]); //TODO need to remove ANSWER_DELAY_TIMEUNITS from this
                rangingDistance[receivedFrame.source] = (rangingTOF[receivedFrame.source] * 300 * TIMEUNITS_TO_US / 4); //TODO should this be divide by 2?
                debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "Distance(%d): %d\n",receivedFrame.source, rangingDistance[receivedFrame.source]);debug_exe();
                break;
            default : break;
        }
 
    //debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "Received From: %d\n",receivedFrame.destination);debug_exe();
    dw.startRX();
}

 

void MM2WayRanging::callbackTX() {
    //dw.readRegister(DW1000_TX_BUFFER, 0, (uint8_t*)&sentFrame, dw.getFramelength());
    switch (rangingFrame.type) {
        case BEACON_READY:
            //No Need to do anything
            break;
        case ANCHOR_TO_BEACON_PING:
            rangingTxTimestamp[rangingFrame.destination] = dw.getTXTimestamp();
            break;
        case BEACON_TO_ANCHOR_RESPONSE:
            //No Need to do anything
            break;
        default: break;
    }
}



bool MM2WayRanging::beacon_requestRanging() {
    float time_before = LocalTimer.read();
    beacon_ready_Send();
    bool sendSuccess = waitForFrameTX(time_before);
    if (sendSuccess) {
        //WAIT FOR FIRST RANGING FROM AN ANCHOR - TIMEOUT AFTER NO RANGING FOR CERTAIN TIME
        float lastRangingTime = LocalTimer.read();
        while((LocalTimer.read() - lastRangingTime) < 0.02f) {
            if (waitForFrameRX(lastRangingTime)) {
                lastRangingTime = LocalTimer.read();
            }
        }
    } else {
        //Send Fail   
    }
    //debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "Range End - %d\n",destination);debug_exe();
}



void MM2WayRanging::anchor_standbyToRange() {
    float time_before = LocalTimer.read();
    waitForFrameRX(time_before);
}


void MM2WayRanging::beacon_ready_Send() {
    rangingFrame.source = address;
    rangingFrame.destination = 0;
    rangingFrame.type = BEACON_READY;
    dw.sendFrame((uint8_t*)&rangingFrame, sizeof(rangingFrame));
}
 
void MM2WayRanging::anchor_to_beacon_Send(uint8_t destination) {
    rangingFrame.source = address;
    rangingFrame.destination = destination;
    rangingFrame.type = ANCHOR_TO_BEACON_PING;
    dw.sendFrame((uint8_t*)&rangingFrame, sizeof(rangingFrame));
}

void MM2WayRanging::beacon_to_anchor_response_Send(uint8_t destination, uint64_t rxTimestamp) {
    rangingFrame.source = address;
    rangingFrame.destination = destination;
    rangingFrame.type = BEACON_TO_ANCHOR_RESPONSE;
    if(rxTimestamp + ANSWER_DELAY_TIMEUNITS > MMRANGING_2POWER40) {
        dw.sendDelayedFrame((uint8_t*)&rangingFrame, sizeof(rangingFrame), rxTimestamp + ANSWER_DELAY_TIMEUNITS - MMRANGING_2POWER40);
    } else {
        dw.sendDelayedFrame((uint8_t*)&rangingFrame, sizeof(rangingFrame), rxTimestamp + ANSWER_DELAY_TIMEUNITS);
    }
}












/*
void MM2WayRanging::correctReceiverTimestamps(uint8_t source){
    if(receiverTimestamps[source][0] > receiverTimestamps[source][1]){
        receiverTimestamps[source][1] += MMRANGING_2POWER40;
        receiverTimestamps[source][2] += MMRANGING_2POWER40;
    }
    if(receiverTimestamps[source][1] > receiverTimestamps[source][2]){
        receiverTimestamps[source][2] += MMRANGING_2POWER40;
    }
}
 
void MM2WayRanging::correctSenderTimestamps(uint8_t source){
    if (senderTimestamps[source][0] > senderTimestamps[source][1]) {
        senderTimestamps[source][1] += MMRANGING_2POWER40;
        senderTimestamps[source][2] += MMRANGING_2POWER40;
        overflow = true;
    } else if (senderTimestamps[source][1] > senderTimestamps[source][2]) {
        senderTimestamps[source][2] += MMRANGING_2POWER40;
        overflow = true;
    } else { 
        overflow = false;
    }
}
*/