diff --git a/keywords.txt b/keywords.txt index 9c8e6dca..edcb4faa 100644 --- a/keywords.txt +++ b/keywords.txt @@ -246,6 +246,8 @@ sendTone KEYWORD2 # PhysicalLayer dropSync KEYWORD2 +setTimerFlag KEYWORD2 +setInterruptSetup KEYWORD2 ####################################### # Constants (LITERAL1) diff --git a/src/Module.cpp b/src/Module.cpp index 72e5d996..ba0674c0 100644 --- a/src/Module.cpp +++ b/src/Module.cpp @@ -251,6 +251,24 @@ void Module::SPItransfer(uint8_t cmd, uint8_t reg, uint8_t* dataOut, uint8_t* da this->SPIendTransaction(); } +void Module::waitForMicroseconds(uint32_t start, uint32_t len) { + #if defined(RADIOLIB_INTERRUPT_TIMING) + (void)start; + if((this->TimerSetupCb != nullptr) && (len != this->_prevTimingLen)) { + _prevTimingLen = len; + this->TimerSetupCb(len); + } + this->TimerFlag = false; + while(!this->TimerFlag) { + this->yield(); + } + #else + while(this->micros() - start < len) { + this->yield(); + } + #endif +} + void Module::pinMode(RADIOLIB_PIN_TYPE pin, RADIOLIB_PIN_MODE mode) { if((pin == RADIOLIB_NC) || (cb_pinMode == nullptr)) { return; diff --git a/src/Module.h b/src/Module.h index b12fe355..f699d5fe 100644 --- a/src/Module.h +++ b/src/Module.h @@ -91,6 +91,25 @@ class Module { */ uint8_t SPIwriteCommand = 0b10000000; + #if defined(RADIOLIB_INTERRUPT_TIMING) + + /*! + \brief Timer interrupt setup callback typedef. + */ + typedef void (*TimerSetupCb_t)(uint32_t len); + + /*! + \brief Callback to timer interrupt setup function when running in interrupt timing control mode. + */ + TimerSetupCb_t TimerSetupCb = nullptr; + + /*! + \brief Timer flag variable to be controlled by a platform-dependent interrupt. + */ + volatile bool TimerFlag = false; + + #endif + // basic methods /*! @@ -241,6 +260,16 @@ class Module { */ void setRfSwitchState(RADIOLIB_PIN_STATUS rxPinState, RADIOLIB_PIN_STATUS txPinState); + /*! + \brief Wait for time to elapse, either using the microsecond timer, or the TimerFlag. + Note that in interrupt timing mode, it is up to the user to set up the timing interrupt! + + \param start Waiting start timestamp, in microseconds. + + \param len Waiting duration, in microseconds; + */ + void waitForMicroseconds(uint32_t start, uint32_t len); + // Arduino core overrides /*! @@ -422,6 +451,10 @@ class Module { RADIOLIB_PIN_TYPE _rxEn = RADIOLIB_NC; RADIOLIB_PIN_TYPE _txEn = RADIOLIB_NC; + #if defined(RADIOLIB_INTERRUPT_TIMING) + uint32_t _prevTimingLen = 0; + #endif + // hardware abstraction layer callbacks // this is placed at the end of Module class because the callback generator macros // screw with the private/public access specifiers