SX1261 and sx1262 common library

Dependents:   SX126xDevKit SX1262PingPong SX126X_TXonly SX126X_PingPong_Demo ... more

Fork of SX126xLib by Gregory Cristian

sx126x.cpp

Committer:
GregCr
Date:
2016-09-23
Revision:
2:4ff11ea92fbe
Parent:
1:35d34672a089
Child:
3:7e3595a9ebe0

File content as of revision 2:4ff11ea92fbe:

/*
 / _____)             _              | |
( (____  _____ ____ _| |_ _____  ____| |__
 \____ \| ___ |    (_   _) ___ |/ ___)  _ \
 _____) ) ____| | | || |_| ____( (___| | | |
(______/|_____)_|_|_| \__)_____)\____)_| |_|
    (C)2016 Semtech

Description: Handling of the node configuration protocol

License: Revised BSD License, see LICENSE.TXT file include in the project

Maintainer: Miguel Luis, Gregory Cristian and Matthieu Verdy
*/
#include "mbed.h"
#include "sx126x.h"
#include "sx126x-hal.h"

/*!
 * Radio registers definition
 *
 */
typedef struct
{
    uint16_t      Addr;                             //!< The address of the register
    uint8_t       Value;                            //!< The value of the register
}RadioRegisters_t;

// [TODO] Is this also applicable for the V2 version of the chip
/*!
 * \brief Radio hardware registers initialization definition
 */
// { Address, RegValue }
#define RADIO_INIT_REGISTERS_VALUE \
{                                  \
    { 0x0722, 0x53 },              \
}

/*!
 * \brief Radio hardware registers initialization
 */
const RadioRegisters_t RadioRegsInit[] = RADIO_INIT_REGISTERS_VALUE;

void SX126x::Init( void )
{
    Reset( );
    IoIrqInit( dioIrq );
    Wakeup( );
    SetRegistersDefault( );
}

void SX126x::SetRegistersDefault( void )
{
    for( uint8_t i = 0; i < sizeof( RadioRegsInit ) / sizeof( RadioRegisters_t ); i++ )
    {
        WriteRegister( RadioRegsInit[i].Addr, RadioRegsInit[i].Value );
    }
}

uint16_t SX126x::GetFirmwareVersion( void )
{
    return( ( ( ReadRegister( 0xA8 ) ) << 8 ) | ( ReadRegister( 0xA9 ) ) );
}

RadioStatus_t SX126x::GetStatus( void )
{
    uint8_t stat = 0;
    RadioStatus_t status;

    ReadCommand( RADIO_GET_STATUS, ( uint8_t * )&stat, 1 );
    status.Value = stat;
    
    
    return( status );
}

void SX126x::SetSleep( SleepParams_t sleepConfig )
{

    WriteCommand( RADIO_SET_SLEEP, &sleepConfig.Value, 1 );
    OperatingMode = MODE_SLEEP;
}

void SX126x::SetStandby( RadioStandbyModes_t standbyConfig )
{
    WriteCommand( RADIO_SET_STANDBY, ( uint8_t* )&standbyConfig, 1 );
    if( standbyConfig == STDBY_RC )
    {
        OperatingMode = MODE_STDBY_RC;
    }
    else
    {
        OperatingMode = MODE_STDBY_XOSC;
    }
}

void SX126x::SetFs( void )
{
    WriteCommand( RADIO_SET_FS, 0, 0 );
    OperatingMode = MODE_FS;
}

void SX126x::SetTx( uint32_t timeout )
{
    uint8_t buf[3];
    buf[0] = ( uint8_t )( ( timeout >> 16 ) & 0xFF );
    buf[1] = ( uint8_t )( ( timeout >> 8 ) & 0xFF );
    buf[2] = ( uint8_t )( timeout & 0xFF );
    WriteCommand( RADIO_SET_TX, buf, 3 );
    OperatingMode = MODE_TX;
}

void SX126x::SetRx( uint32_t timeout )
{
    uint8_t buf[3];
    buf[0] = ( uint8_t )( ( timeout >> 16 ) & 0xFF );
    buf[1] = ( uint8_t )( ( timeout >> 8 ) & 0xFF );
    buf[2] = ( uint8_t )( timeout & 0xFF );
    WriteCommand( RADIO_SET_RX, buf, 3 );
    OperatingMode = MODE_RX;
}

void SX126x::SetRxDutyCycle( uint32_t rxTime, uint32_t sleepTime )
{
    uint8_t buf[6];

    buf[0] = ( uint8_t )( ( rxTime >> 16 ) & 0xFF );
    buf[1] = ( uint8_t )( ( rxTime >> 8 ) & 0xFF );
    buf[2] = ( uint8_t )( rxTime & 0xFF );
     buf[0] = ( uint8_t )( ( sleepTime >> 16 ) & 0xFF );
    buf[1] = ( uint8_t )( ( sleepTime >> 8 ) & 0xFF );
    buf[2] = ( uint8_t )( sleepTime & 0xFF );
    WriteCommand( RADIO_SET_RXDUTYCYCLE, buf, 6 );
    OperatingMode = MODE_RX;
}

void SX126x::SetCad( void )
{
    WriteCommand( RADIO_SET_CAD, 0, 0 );
    OperatingMode = MODE_CAD;
}

void SX126x::SetAutoTxRx( uint32_t time, uint8_t intMode, uint32_t timeout )
{
    uint32_t compensatedTime = time - ( uint16_t )AUTO_RX_TX_OFFSET;
    uint8_t buf[7];

    buf[0] = ( uint8_t )( ( compensatedTime >> 16 ) & 0xFF );
    buf[1] = ( uint8_t )( ( compensatedTime >> 8 ) & 0xFF );
    buf[2] = ( uint8_t )( compensatedTime & 0xFF );
    buf[3] = intMode;
    buf[4] = ( uint8_t )( ( timeout >> 16 ) & 0xFF );
    buf[5] = ( uint8_t )( ( timeout >> 8 ) & 0xFF );
    buf[6] = ( uint8_t )( timeout & 0xFF );
    WriteCommand( RADIO_SET_AUTOTXRX, buf, 7 );
}


void SX126x::SetTxContinuousWave( void )
{
    WriteCommand( RADIO_SET_TXCONTINUOUSWAVE, 0, 0 );
}

void SX126x::SetTxContinuousPreamble( void )
{
    WriteCommand( RADIO_SET_TXCONTINUOUSPREAMBLE, 0, 0 );
}

void SX126x::SetPacketType( RadioPacketType_t packetType )
{
    // Save packet type internally to avoid questioning the radio
    this->PacketType = packetType;

    WriteCommand( RADIO_SET_PACKETTYPE, ( uint8_t* )&packetType, 1 );
}

RadioPacketType_t SX126x::GetPacketType( void )
{
    return this->PacketType;
}

void SX126x::SetRfFrequency( uint32_t frequency )
{
    uint8_t buf[4];
    uint32_t freq = 0;

    freq = ( uint32_t )( ( double )frequency / ( double )FREQ_STEP );
    buf[0] = ( uint8_t )( ( freq >> 24 ) & 0xFF );
    buf[1] = ( uint8_t )( ( freq >> 16 ) & 0xFF );
    buf[2] = ( uint8_t )( ( freq >> 8 ) & 0xFF );
    buf[3] = ( uint8_t )( freq & 0xFF );
    WriteCommand( RADIO_SET_RFFREQUENCY, buf, 3 );
}

void SX126x::SetTxParams( int8_t power, RadioRampTimes_t rampTime )
{
    uint8_t buf[2];
    
    buf[0] = power ;
    buf[1] = ( uint8_t )rampTime;
    WriteCommand( RADIO_SET_TXPARAMS, buf, 2 );
}

void SX126x::SetCadConfig( RadioLoRaCadSymbols_t cadSymbolNum , uint8_t cadExitMode, uint32_t cadRxTxTimeout)
{
    uint8_t buf[5];
    buf[0] = ( uint8_t )cadSymbolNum;
    buf[1] = cadExitMode;
    buf[2] = ( uint8_t )( ( cadRxTxTimeout >> 16 ) & 0xFF );
    buf[3] = ( uint8_t )( ( cadRxTxTimeout >> 8 ) & 0xFF );
    buf[4] = ( uint8_t )( cadRxTxTimeout & 0xFF );
    WriteCommand( RADIO_SET_CADPARAMS, buf, 5 );
    OperatingMode = MODE_CAD;
}

void SX126x::SetBufferBaseAddresses( uint8_t txBaseAddress, uint8_t rxBaseAddress )
{
    uint8_t buf[2];

    buf[0] = txBaseAddress;
    buf[1] = rxBaseAddress;
    WriteCommand( RADIO_SET_BUFFERBASEADDRESS, buf, 2 );
}

void SX126x::SetModulationParams( ModulationParams_t *modulationParams )
{
    uint8_t n;

    // Check if required configuration corresponds to the stored packet type
    // If not, silently update radio packet type
    if( this->PacketType != modulationParams->PacketType )
    {
        this->SetPacketType( modulationParams->PacketType );
    }

    switch( modulationParams->PacketType )
    {
        case PACKET_TYPE_GFSK:
            n = 8;
            break;
        case PACKET_TYPE_GMSK:
            n = 8;
            break;
        case PACKET_TYPE_BPSK:
            n = 5;
            break;
        case PACKET_TYPE_LORA:
        case PACKET_TYPE_RANGING:
            n = 3;
            break;
        case PACKET_TYPE_NONE:
            return;
    }
    WriteCommand( RADIO_SET_MODULATIONPARAMS, modulationParams->Params.Buffer, n );
}

void SX126x::SetPacketParams( PacketParams_t *packetParams )
{
    uint8_t n;
    
    // Check if required configuration corresponds to the stored packet type
    // If not, silently update radio packet type
    if( this->PacketType != packetParams->PacketType )
    {
        this->SetPacketType( packetParams->PacketType );
    }

    switch( packetParams->PacketType )
    {
        case PACKET_TYPE_GFSK:
            n = 8;
            break;
        case PACKET_TYPE_BPSK:
            n = 8;
            break;   
        case PACKET_TYPE_LORA:
        case PACKET_TYPE_RANGING:
            n = 5;
            break;
        case PACKET_TYPE_NONE:
           return;
    }
    WriteCommand( RADIO_SET_PACKETPARAMS, packetParams->Params.Buffer, n );
}

void SX126x::GetRxBufferStatus( uint8_t *payloadLength, uint8_t *rxStartBufferPointer )
{
    uint8_t status[2];

    ReadCommand( RADIO_GET_RXBUFFERSTATUS, status, 2 );

    *payloadLength = status[0];
    *rxStartBufferPointer = status[1];
}

void SX126x::GetPacketStatus( PacketStatus_t *pktStatus )
{
    uint8_t status[3];


    ReadCommand( RADIO_GET_PACKETSTATUS, status, 3 );

    pktStatus->packetType = this -> GetPacketType( );
    switch( pktStatus->packetType )
    {
        case PACKET_TYPE_GFSK:
            pktStatus->Gfsk.RxStatus = status[0];
            pktStatus->Gfsk.RssiSync = -status[1] / 2;
            pktStatus->Gfsk.RssiAvg = -status[2] / 2;
            break;

        case PACKET_TYPE_LORA:
        case PACKET_TYPE_RANGING:
            pktStatus->LoRa.RssiPkt = -status[0] / 2;
            ( status[1] < 128 ) ? ( pktStatus->LoRa.SnrPkt = status[1] / 4 ) : ( pktStatus->LoRa.SnrPkt = ( ( status[1] - 256 ) /4 ) );
            pktStatus->LoRa.SignalRssiPkt = -status[2] / 2;
            break;

        case PACKET_TYPE_NONE:
            // In that specific case, we set everything in the pktStatus to zeros
            // and reset the packet type accordingly
            memset( pktStatus, 0, sizeof( PacketStatus_t ) );
            pktStatus->packetType = PACKET_TYPE_NONE;
            break;
    }
}

int8_t SX126x::GetRssiInst( void )
{
    int8_t rssi;

    ReadCommand( RADIO_GET_RSSIINST, ( uint8_t* )&rssi, 1 );
    return -rssi / 2;
}

void SX126x::GetStats( RxCounter_t *rxCounter )
{
    uint8_t status[6];


    rxCounter->packetType = this -> GetPacketType( );
    ReadCommand( RADIO_GET_STATS, status, 6 );
    rxCounter->NbPktReceived = ( status[0] << 8 ) | status[1];
    rxCounter->NbPktCrcOk = ( status[2] << 8 ) | status[3];
    rxCounter->NbPktLengthError = ( status[4] << 8 ) | status[4];
}

void SX126x::ResetStats(  )
{
    uint8_t status[6];

    memset( status, 0, sizeof( status ) );
    WriteCommand( RADIO_RESET_STATS, status, 6 );
}

uint8_t SX126x::GetError()
{
    uint8_t error;

    ReadCommand( RADIO_GET_ERROR, &error, 1 );
    return error; 
}


void SX126x::SetDioIrqParams( uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask, uint16_t dio3Mask )
{
    uint8_t buf[8];

    buf[0] = ( uint8_t )( ( irqMask >> 8 ) & 0x00FF );
    buf[1] = ( uint8_t )( irqMask & 0x00FF );
    buf[2] = ( uint8_t )( ( dio1Mask >> 8 ) & 0x00FF );
    buf[3] = ( uint8_t )( dio1Mask & 0x00FF );
    buf[4] = ( uint8_t )( ( dio2Mask >> 8 ) & 0x00FF );
    buf[5] = ( uint8_t )( dio2Mask & 0x00FF );
    buf[6] = ( uint8_t )( ( dio3Mask >> 8 ) & 0x00FF );
    buf[7] = ( uint8_t )( dio3Mask & 0x00FF );
    WriteCommand( RADIO_CFG_DIOIRQ, buf, 8 );
}

uint16_t SX126x::GetIrqStatus( void )
{
    uint8_t irqStatus[2];
    ReadCommand( RADIO_GET_IRQSTATUS, irqStatus, 2 );
    return ( irqStatus[0] << 8 ) | irqStatus[1];
}

void SX126x::ClearIrqStatus( uint16_t irq )
{
    uint8_t buf[2];

    buf[0] = ( uint8_t )( ( ( uint16_t )irq >> 8 ) & 0x00FF );
    buf[1] = ( uint8_t )( ( uint16_t )irq & 0x00FF );
    WriteCommand( RADIO_CLR_IRQSTATUS, buf, 2 );
}

void SX126x::Calibrate( CalibrationParams_t calibParam )
{
    WriteCommand( RADIO_CALIBRATE, &calibParam.Value, 1 );
}

void SX126x::SetRegulatorMode( uint8_t mode )
{
    WriteCommand( RADIO_SET_REGULATORMODE, &mode, 1 );
}


void SX126x::SetLongPreamble( uint8_t enable )
{
    WriteCommand( RADIO_SET_LONGPREAMBLE, &enable, 1 );
}

void SX126x::SetPayload( uint8_t *buffer, uint8_t size )
{
    WriteBuffer( 0x00, buffer, size );
}

uint8_t SX126x::GetPayload( uint8_t *buffer, uint8_t *size,  uint8_t maxSize )
{
    uint8_t offset;

    GetRxBufferStatus( size, &offset );
    if(*size > maxSize)
    {
        return 1;
    }
    ReadBuffer( offset, buffer, *size );
    return 0;
}

void SX126x::SendPayload( uint8_t *payload, uint8_t size, uint32_t timeout )
{
    SetPayload( payload, size );
    SetTx( timeout );
}

uint8_t SX126x::SetSyncWord( uint8_t *syncWord )
{
    uint8_t syncwordSize = 8;

    WriteRegister( REG_LR_SYNCWORDBASEADDRESS, syncWord, syncwordSize );
    return 0;
}

void SX126x::SetCrcSeed( uint8_t *seed )
{
    switch( GetPacketType( ) )
    {
        case PACKET_TYPE_GFSK:
            WriteRegister( REG_LR_CRCSEEDBASEADDR, seed, 2 );
            break;
        default:
            break;
    }
}

void SX126x::SetCrcPolynomial( uint8_t *polynomial )
{
    switch( GetPacketType( ) )
    {
        case PACKET_TYPE_GFSK:
            WriteRegister( REG_LR_CRCPOLYBASEADDR, polynomial, 2 );
            break;
        default:
            break;
    }
}

void SX126x::SetWhiteningSeed( uint8_t seed )
{
    switch( GetPacketType( ) )
    {
        case PACKET_TYPE_GFSK:
            WriteRegister( REG_LR_WHITSEEDBASEADDR, seed );
            break;
        default:
            break;
    }
}

void SX126x::SetRangingIdLength( RadioRangingIdCheckLen_t length )
{
    switch( GetPacketType( ) )
    {
        case PACKET_TYPE_RANGING:
            WriteRegister( REG_LR_RANGINGIDCHECKLENGTH, ( ( ( ( uint8_t )length ) & 0x03 ) << 6 ) | ( ReadRegister( REG_LR_RANGINGIDCHECKLENGTH ) & 0x3F ) );
            break;
        default:
            break;
    }
}

void SX126x::SetDeviceRangingAddress( uint32_t address )
{
    uint8_t addrArray[] = { ( uint8_t )( ( address >> 24 ) & 0xFF ) , 
                            ( uint8_t )( ( address >> 16 ) & 0xFF ),
                            ( uint8_t )( ( address >> 8 ) & 0xFF ),
                            ( uint8_t )( ( address >> 0 ) & 0xFF ) };
    
    WriteRegister( REG_LR_DEVICERANGINGADDR, addrArray, 4 );
}

void SX126x::SetRangingRequestAddress( uint32_t address )
{
     uint8_t addrArray[] = { ( uint8_t )( ( address >> 24 ) & 0xFF ) , 
                            ( uint8_t )( ( address >> 16 ) & 0xFF ),
                            ( uint8_t )( ( address >> 8 ) & 0xFF ),
                            ( uint8_t )( ( address >> 0 ) & 0xFF ) };
                            
    WriteRegister( REG_LR_REQUESTRANGINGADDR, addrArray, 4 );
    
}

int32_t SX126x::GetRangingResult( RadioRangingResultType_t resultType )
{
    int32_t val = 0;
    uint32_t addr = REG_LR_RANGINGRESULTRAWBASEADDR + (uint8_t)resultType;
    //switch( GetPacketType( ) )
    //{
    //    case PACKET_TYPE_RANGING:
            val = ( ( ReadRegister( addr ) << 16 ) | ( ReadRegister( addr + 1 ) << 8 ) | ( ReadRegister( addr + 2 ) ) );
            if( ( val & 0x800000 ) == 0x800000 )
            {
                val |= 0xFF000000;
            }
    //        break;
    //    default:
    //        break;
    //}
    return val;
}

void SX126x::SetRangingCalibration( uint16_t cal )
{
        WriteRegister( REG_LR_RANGINGRERXTXDELAYCAL, ( uint8_t )( ( cal >> 8 ) & 0xFF ) );
        WriteRegister( REG_LR_RANGINGRERXTXDELAYCAL + 1, ( uint8_t )( ( cal ) & 0xFF ) );
}

int8_t SX126x::ParseHexFileLine( char* line )
{
    uint16_t addr;
    uint16_t n;
    uint8_t code;
    uint8_t bytes[256];

    if( GetHexFileLineFields( line, bytes, &addr, &n, &code ) != 0 )
    {
        if( code == 0 )
        {
            WriteRegister( addr, bytes, n );
        }
        if( code == 1 )
        { // end of file
            //return 2;
        }
        if( code == 2 )
        { // begin of file
            //return 3;
        }
    }
    else
    {
        return 0;
    }
    return 1;
}

int8_t SX126x::GetHexFileLineFields( char* line, uint8_t *bytes, uint16_t *addr, uint16_t *num, uint8_t *code )
{
    uint16_t sum, len, cksum;
    char *ptr;

    *num = 0;
    if( line[0] != ':' )
    {
        return 0;
    }
    if( strlen( line ) < 11 )
    {
        return 0;
    }
    ptr = line + 1;
    if( !sscanf( ptr, "%02hx", &len ) )
    {
        return 0;
    }
    ptr += 2;
    if( strlen( line ) < ( 11 + ( len * 2 ) ) )
    {
        return 0;
    }
    if( !sscanf( ptr, "%04hx", addr ) )
    {
        return 0;
    }
    ptr += 4;
    if( !sscanf( ptr, "%02hhx", code ) )
    {
        return 0;
    }
    ptr += 2;
    sum = ( len & 255 ) + ( ( *addr >> 8 ) & 255 ) + ( *addr & 255 ) + ( ( *code >> 8 ) & 255 ) + ( *code & 255 );
    while( *num != len )
    {
        if( !sscanf( ptr, "%02hhx", &bytes[*num] ) )
        {
            return 0;
        }
        ptr += 2;
        sum += bytes[*num] & 255;
        ( *num )++;
        if( *num >= 256 )
        {
            return 0;
        }
    }
    if( !sscanf( ptr, "%02hx", &cksum ) )
    {
        return 0;
    }
    if( ( ( sum & 255 ) + ( cksum & 255 ) ) & 255 )
    {
        return 0; // checksum error
    }

    return 1;
}

void SX126x::OnDioIrq( void )
{
    if(onCustomDioIrq != NULL)
    {
        onCustomDioIrq();
        return;
    }
    
    uint16_t irqRegs = GetIrqStatus( );
    LastIrqs = irqRegs;
    ClearIrqStatus( IRQ_RADIO_ALL );


#if( SX126x_DEBUG == 1 )
    DigitalOut TEST_PIN_1( D14 );
    DigitalOut TEST_PIN_2( D15 );
    for( int i = 0x8000; i != 0; i >>= 1 )
    {
        TEST_PIN_2 = 0;
        TEST_PIN_1 = ( ( irqRegs & i ) != 0 ) ? 1 : 0;
        TEST_PIN_2 = 1;
    }
    TEST_PIN_1 = 0;
    TEST_PIN_2 = 0;
#endif


    //IRQ_TX_DONE                             = 0x0001,
    if( irqRegs & IRQ_TX_DONE )
    {
        if( txDone != NULL )
        {
            txDone( );
        }
    }

    //IRQ_RX_DONE                             = 0x0002,
    if( irqRegs & IRQ_RX_DONE )
    {
        if( rxDone != NULL )
        {
            rxDone( );
        }
    }

    //IRQ_PREAMBLE_DETECTED                   = 0x0004,
    if( irqRegs & IRQ_PREAMBLE_DETECTED )
    {
        if( rxPblSyncWordHeader != NULL )
        {
            rxPblSyncWordHeader( IRQ_PBL_DETECT_CODE);
        }
    }

    //IRQ_SYNCWORD_VALID                      = 0x0008,
    if( irqRegs & IRQ_SYNCWORD_VALID )
    {
        if( rxPblSyncWordHeader != NULL )
        {
            rxPblSyncWordHeader( IRQ_SYNCWORD_VALID_CODE  );
        }
    }

    //IRQ_HEADER_VALID                        = 0x0010,
    if ( irqRegs & IRQ_HEADER_VALID ) 
    {
        if( rxPblSyncWordHeader != NULL )
        {
            rxPblSyncWordHeader( IRQ_hEADER_VALID_CODE );
        }
    } 

    //IRQ_HEADER_ERROR                        = 0x0020,    
    if( irqRegs & IRQ_HEADER_ERROR )
    {
        if( rxError != NULL )
        {
            rxError( IRQ_HEADER_ERROR_CODE );
        }
    }  
    
    //IRQ_GFSK_ERROR                          = 0x0040,
    //IRQ_LORA_CRC_ERROR                      = 0x0040,       //shared with IRQ_GFSK_ERROR
    if( irqRegs & IRQ_GFSK_ERROR )      // same as IRQ_LORA_CRC_ERROR
    {
        if( rxError != NULL )
        {
            rxError( IRQ_GFSK_ERROR_CODE );
        }
    }
    
    //IRQ_CAD_DONE                            = 0x0080,
    //IRQ_CAD_ACTIVITY_DETECTED               = 0x0100,
    if(  irqRegs & IRQ_CAD_DONE )
    {
        bool detected = ( ( irqRegs & IRQ_CAD_ACTIVITY_DETECTED ) == IRQ_CAD_ACTIVITY_DETECTED );

        if( cadDone != NULL )
        {
            cadDone( detected );
        }
                    
    }

    //IRQ_RX_TX_TIMEOUT                       = 0x0200,
    if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT )
    {
        if( rxTxTimeout != NULL )
        {
            rxTxTimeout( );
        }
    }
    

    //IRQ_RANGING_SLAVE_REQUEST_VALID         = 0x0400,
    if( irqRegs &  IRQ_RANGING_SLAVE_REQUEST_VALID) 
    {
        if( rangingDone != NULL )
        {
            rangingDone( IRQ_RANGING_SLAVE_VALID_CODE );
        }
    } 

    //IRQ_RANGING_SLAVE_REQUEST_DISCARDED     = 0x0800,
    if( irqRegs & IRQ_RANGING_SLAVE_REQUEST_DISCARDED )  
    {
        if( rangingDone != NULL )
        {
            rangingDone( IRQ_RANGING_SLAVE_ERROR_CODE );
        }
    } 

    //IRQ_RANGING_SLAVE_RESPONSE_DONE         = 0x1000,
    if( irqRegs & IRQ_RANGING_SLAVE_RESPONSE_DONE )
    {
        if( rangingDone != NULL )
        {
            rangingDone( IRQ_RANGING_SLAVE_RESPONSE_DONE_CODE );
        }
    }

    //IRQ_RANGING_MASTER_RESULT_VALID         = 0x2000,
    if( irqRegs & IRQ_RANGING_MASTER_RESULT_VALID ) 
    {
        if( rangingDone != NULL )
        {
            rangingDone( IRQ_RANGING_MASTER_VALID_CODE );
        }
    }

    //IRQ_RANGING_MASTER_RESULT_TIMEOUT       = 0x4000,
    if( irqRegs & IRQ_RANGING_MASTER_RESULT_TIMEOUT )
    {
        if( rangingDone != NULL )
        {
            rangingDone( IRQ_RANGING_MASTER_TIMEOUT_CODE );
        }
    }
                    

}