RadioHead

RHGenericDriver.cpp

Committer:
danjulio
Date:
2017-06-11
Revision:
0:e69d086cb053

File content as of revision 0:e69d086cb053:

// RHGenericDriver.cpp
//
// Copyright (C) 2014 Mike McCauley
// $Id: RHGenericDriver.cpp,v 1.21 2017/03/04 00:59:41 mikem Exp $
//
// Ported to mbed - support only a single radio - Dan Julio - 5/2017 
//

#include <RHGenericDriver.h>

RHGenericDriver::RHGenericDriver()
    :
    _mode(RHModeInitialising),
    _thisAddress(RH_BROADCAST_ADDRESS),
    _txHeaderTo(RH_BROADCAST_ADDRESS),
    _txHeaderFrom(RH_BROADCAST_ADDRESS),
    _txHeaderId(0),
    _txHeaderFlags(0),
    _rxBad(0),
    _rxGood(0),
    _txGood(0),
    _cad_timeout(0)
{
}

bool RHGenericDriver::init()
{
    return true;
}

// Blocks until a valid message is received
void RHGenericDriver::waitAvailable()
{
    while (!available())
        Thread::yield();
}

// Blocks until a valid message is received or timeout expires
// Return true if there is a message available
// Works correctly even on millis() rollover
bool RHGenericDriver::waitAvailableTimeout(uint16_t timeout)
{
    _waitTimer.reset();
    _waitTimer.start();

    while (_waitTimer.read_ms() < timeout)
    {
        if (available())
        {
            _waitTimer.stop();
            return true;
        }
        Thread::yield();
    }
    _waitTimer.stop();
    return false;
}

bool RHGenericDriver::waitPacketSent()
{
    while (_mode == RHModeTx)
    Thread::yield(); // Wait for any previous transmit to finish
    return true;
}

bool RHGenericDriver::waitPacketSent(uint16_t timeout)
{
    _waitTimer.reset();
    _waitTimer.start();
    while (_waitTimer.read_ms() < timeout)
    {
        if (_mode != RHModeTx) // Any previous transmit finished?
        {
            _waitTimer.stop();
            return true;
        }
        Thread::yield();
    }
    _waitTimer.stop();
    return false;
}

// Wait until no channel activity detected or timeout
bool RHGenericDriver::waitCAD()
{
    if (!_cad_timeout)
        return true;

    // Wait for any channel activity to finish or timeout
    // Sophisticated DCF function...
    // DCF : BackoffTime = random() x aSlotTime
    // 100 - 1000 ms
    // 10 sec timeout
    _waitTimer.reset();
    _waitTimer.start();
    while (isChannelActive())
    {
        if (_waitTimer.read_ms() > _cad_timeout)
        {
            _waitTimer.stop();
            return false;
        }
        
        wait_ms(100);
    }

    _waitTimer.stop();
    return true;
}

// subclasses are expected to override if CAD is available for that radio
bool RHGenericDriver::isChannelActive()
{
    return false;
}

void RHGenericDriver::setPromiscuous(bool promiscuous)
{
    _promiscuous = promiscuous;
}

void RHGenericDriver::setThisAddress(uint8_t address)
{
    _thisAddress = address;
}

void RHGenericDriver::setHeaderTo(uint8_t to)
{
    _txHeaderTo = to;
}

void RHGenericDriver::setHeaderFrom(uint8_t from)
{
    _txHeaderFrom = from;
}

void RHGenericDriver::setHeaderId(uint8_t id)
{
    _txHeaderId = id;
}

void RHGenericDriver::setHeaderFlags(uint8_t set, uint8_t clear)
{
    _txHeaderFlags &= ~clear;
    _txHeaderFlags |= set;
}

uint8_t RHGenericDriver::headerTo()
{
    return _rxHeaderTo;
}

uint8_t RHGenericDriver::headerFrom()
{
    return _rxHeaderFrom;
}

uint8_t RHGenericDriver::headerId()
{
    return _rxHeaderId;
}

uint8_t RHGenericDriver::headerFlags()
{
    return _rxHeaderFlags;
}

int8_t RHGenericDriver::lastRssi()
{
    return _lastRssi;
}

RHGenericDriver::RHMode  RHGenericDriver::mode()
{
    return _mode;
}

void  RHGenericDriver::setMode(RHMode mode)
{
    _mode = mode;
}

bool  RHGenericDriver::sleep()
{
    return false;
}

// Diagnostic help
void RHGenericDriver::printBuffer(const char* prompt, const uint8_t* buf, uint8_t len)
{
    uint8_t i;

    printf("%s", prompt);
    for (i = 0; i < len; i++)
    {
        if (i % 16 == 15)
            printf("0x%x\n", buf[i]);
        else
        {
            printf("0x%x ", buf[i]);
        }
    }
    printf("\n");
}

uint16_t RHGenericDriver::rxBad()
{
    return _rxBad;
}

uint16_t RHGenericDriver::rxGood()
{
    return _rxGood;
}

uint16_t RHGenericDriver::txGood()
{
    return _txGood;
}

void RHGenericDriver::setCADTimeout(unsigned long cad_timeout)
{
    _cad_timeout = cad_timeout;
}