Version FC

Dependencies:   DmTftLibrary eeprom SX1280Lib filesystem mbed

Fork of MSNV2-Terminal_V1-5 by Francis CHATAIN

Revision:
8:cd489b7c49a0
Child:
13:5414193da1de
diff -r 1d890cab51bd -r cd489b7c49a0 Lora.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Lora.cpp	Wed Aug 22 13:03:00 2018 +0000
@@ -0,0 +1,457 @@
+/*
+ * MISNet   
+ *
+ *  Lora:   Radio Management 
+ *
+ *  Created on: August 17, 2018       Author: Francis CHATAIN
+ *
+ */
+
+
+// =====================================  Includes
+#include "Lora.h"
+#include "mbed.h"
+#include "main.h"
+#include "sx1280-hal.h"
+
+// ==========================================================================  DEFINE
+#define MODE_LORA         // Lora modulation 
+
+#define TX_TIMEOUT_VALUE        100                         // ms   Number of tick size steps for tx timeout
+#define RX_TIMEOUT_VALUE        100                         // ms   Number of tick size steps for rx timeout
+#define RX_TIMEOUT_TICK_SIZE    RADIO_TICK_SIZE_1000_US     // Size of ticks (used for Tx and Rx timeout)
+#define MODE_ADDR               0x8000 
+
+
+// ==========================================================================  HW 
+DigitalOut  F_CS        ( D6 )  ;     // MBED description of pin
+DigitalOut  SD_CS       ( D8 )  ;     // MBED description of pin
+DigitalOut  ANT_SW      ( A3 )  ;
+DigitalOut  TxLed       ( A4 )  ;
+DigitalOut  RxLed       ( A5 )  ;
+
+
+// ==========================================================================  VARIABLES 
+uint16_t    RxIrqMask ;       // Mask of IRQs to listen to in rx mode
+uint16_t    TxIrqMask ;       // Mask of IRQs to listen to in tx mode
+
+
+uint32_t    valueTimeTx      ; 
+uint32_t    valueTimeLoop    ;
+
+int         dataCounter     = 0 ;
+uint8_t     oldFreq         ; 
+uint8_t     oldBw           ; 
+uint8_t     oldPwr          ; 
+uint8_t     oldSf           ; 
+uint8_t     oldTimer        ; 
+
+// States of the application
+typedef enum  { APP_LOWPOWER, APP_RX, APP_RX_TIMEOUT, APP_RX_ERROR, APP_TX, APP_TX_TIMEOUT, } AppStates_t ;
+AppStates_t AppState = APP_LOWPOWER;        // Init State of the application
+
+PacketStatus_t  PacketStatus        ;
+int8_t          RssiValue    = 0    ;
+int8_t          SnrValue     = 0    ;
+
+ModulationParams_t          modulationParams;
+PacketParams_t              PacketParams    ;        // Locals parameters and status for radio API
+PacketStatus_t              packetStatus    ;        // NEED TO BE OPTIMIZED, COPY OF STUCTURE ALREADY EXISTING
+
+uint32_t                    RF_FREQUENCY        ;   // HzNominal frequency
+RadioLoRaBandwidths_t       LORA_BW             ;   /* 200; 400; 800; 1600 */
+RadioLoRaSpreadingFactors_t LORA_SF             ;   /* SF5; SF6=; SF7; SF8 ; SF9; SF10; SF11 ; SF12 */
+int8_t                      TX_OUTPUT_POWER     ;   /* Output power in dBm [-18..+13] dBm */ 
+uint8_t                     BUFFER_SIZE_MAX     ;   /* Payload size max */
+int16_t                     TIMER               ;   /* timer entre reemission en ms */
+uint8_t                     BUFFER_SIZE_MIN     ;   /* Payload return size */
+
+
+// ==========================================================================  Function  
+void        initRadio              () ;
+void        setRadioTx             () ;
+void        setRadioRx             () ;
+void        watchDogRxCRNoReceived () ; 
+
+
+
+Timer       timerRadio       ;
+Timeout     watchDogRx          ;
+Timeout     watchDogTx          ;
+
+void OnTxDone       ( void );               // Function to be executed on Radio Tx Done event
+void OnRxDone       ( void );               // Function to be executed on Radio Rx Done event
+void OnTxTimeout    ( void );               // Function executed on Radio Tx Timeout event
+void OnRxTimeout    ( void );               // Function executed on Radio Rx Timeout event
+void OnRxError      ( IrqErrorCode_t );     // Function executed on Radio Rx Error event
+
+RadioCallbacks_t callbacks  =  {
+    &OnTxDone,        // txDone
+    &OnRxDone,        // rxDone
+    NULL,             // syncWordDone
+    NULL,             // headerDone
+    &OnTxTimeout,     // txTimeout
+    &OnRxTimeout,     // rxTimeout
+    &OnRxError,       // rxError
+    NULL,             // rangingDone
+    NULL,             // cadDone
+};
+
+//                    mosi, miso,   sclk,  nss,  busy , dio1 , dio2, dio3, rst , callbacks...
+SX1280Hal Radio     ( D11 , D12 ,   D13 ,  D7 ,  D3   , D5   , NC  , NC  , A0  , &callbacks );
+
+
+
+//===============================================================================================================================
+void initLora (uint32_t rf,RadioLoRaBandwidths_t bw,RadioLoRaSpreadingFactors_t sf,int8_t pwr) 
+//===============================================================================================================================
+{
+        // Default value initialisation 
+    printf( "*** LORA ***  Lora Initialisation    \r\n");
+    
+    RxIrqMask = IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT;       // Mask of IRQs to listen to in rx mode
+    TxIrqMask = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT;       // Mask of IRQs to listen to in tx mode
+
+    RF_FREQUENCY        =   rf              ;   // HzNominal frequency
+    LORA_BW             =   bw              ;   /* 200; 400; 800; 1600 */
+    LORA_SF             =   sf              ;   /* SF5; SF6=; SF7; SF8 ; SF9; SF10; SF11 ; SF12 */
+    TX_OUTPUT_POWER     =   pwr             ;   /* Output power in dBm [-18..+13] dBm */ 
+    BUFFER_SIZE_MAX     =   100             ;   /* Payload size max */
+    BUFFER_SIZE_MIN     =   8               ;   /* Payload return size */
+    TIMER               =   1000            ;   /* timer entre reemission en ms */ 
+    
+    
+    
+    Radio.Reset                 ()              ;  
+    Radio.Init                  ()              ;
+    initRadio                   ()              ;            
+    Radio.SetRegulatorMode      ( USE_DCDC )    ;       // Can also be set in LDO mode but consume more power
+    wait_ms                     ( 10 )          ;       // wait for on board DC/DC start-up time
+    
+    TxLed   = 0     ;
+    RxLed   = 0     ;
+
+}
+
+
+//===============================================================================================================================
+void sendMessageLora () {
+//===============================================================================================================================
+    uint8_t         Buffer          [BUFFER_SIZE_MAX]       ;           // Buffer
+    char            frameMISNET     [BUFFER_SIZE_MAX]       ;           // Misnet Frame
+    uint8_t         *pointer                                ;
+    char            *ptr_int                                ;
+    
+    
+    dataCounter = dataCounter + 1 ;
+    memset  ( &Buffer       , 0x00, BUFFER_SIZE_MAX );
+    memset  ( &frameMISNET  , 0x00, BUFFER_SIZE_MAX );
+    
+ 
+    uint16_t    clearPart           =   0x0     ; 
+    
+    uint32_t    servicePayload      =   0x0     ; 
+    //char        serviceMessage[16]              ;     // TRACES
+     
+    uint8_t     SFT                 =   0       ;
+    uint8_t     DFT                 =   0       ;
+    uint8_t     FDL                 =   8       ;
+    uint8_t     BL                  =   7       ;
+    uint8_t     DMI                 =   66      ;
+    uint16_t    RCA                 =   0xBEEF & 0x7FFF ;
+    uint32_t    MIC                 =   0xCAFECAFE  & 0xFFFFFFFF  ;
+ 
+
+    clearPart   =  MODE_ADDR | ( ID_TERMINAL << 6 ) |  ID_GATEWAY ; 
+    printf( "*** LORA ***  CLEAR PART= %8X \r\n ", clearPart);
+
+    servicePayload =  (uint32_t)( (SFT & 0x03)  << 30) | 
+                      (uint32_t)( (DFT & 0x03)  << 28) | 
+                      (uint32_t)( (FDL & 0x3F)  << 22) | 
+                      (uint32_t)( (BL  & 0x07)  << 19) | 
+                      (uint32_t)( (DMI & 0xFF)  << 11) | 
+                      (RCA & 0x7FF)                   ;
+                      
+    //sprintf (serviceMessage, "%08X%08X", servicePayload, MIC) ;    // traces 
+    //printf( "*** LORA ***  SERVICE Payload = %08X \r\n ", servicePayload);
+    //printf( "*** LORA ***  SERVICE MIC     = %08X \r\n ", MIC);
+    
+    // CLEAR PART + Indianess correction 
+    pointer = (uint8_t*) &clearPart ;       for (int i = 0, j=1 ; i<2 ; i++, j--)  frameMISNET[j]   = pointer[i] ;
+       
+    // SERVICE + Indianess correction 
+    pointer = (uint8_t*) &servicePayload ;  for (int i=0, j=3 ; i<4 ; i++, j--)    frameMISNET[2+i] = pointer[j] ;
+    pointer = (uint8_t*) &MIC ;             for (int i=0, j=3 ; i<4 ; i++, j--)    frameMISNET[6+i] = pointer[j] ;
+  
+    printf( "*** LORA ***  START Buffer  "); for (int i = 0 ; i<10 ; i++)  printf ("%02X,", frameMISNET[i] ) ; printf( "\n") ; 
+
+    
+    int n = sprintf (frameMISNET, "%1c%1c",  ID_TERMINAL, ID_GATEWAY);
+   
+    pointer = (uint8_t*) &dataCounter  ; for (int i = 0 ; i<4 ; i++)  frameMISNET[2+i] = pointer[i] ;
+                                                                 //(int32*)&frameMISNET[2]=(int32*)&ptr_int; // -> aton OR ntoa                                                                                                                         
+
+    printf( "*** LORA ***  TX SEND   %05d  ", dataCounter);
+       for (int i = 0 ; i<10 ; i++)  printf ("%d,", frameMISNET[i] ) ; printf( "\n") ; 
+       
+    
+    // Send SF, BW, COUNTER, POWER, FREQ, TIMETX, TIMELOOP, RSSIVALUE
+    frameMISNET[6] = LORA_SF            ; 
+    ptr_int = (char*) &LORA_BW          ; 
+    frameMISNET[7]= ptr_int[1]          ;   
+    frameMISNET[8]= ptr_int[0]          ;
+    frameMISNET[9] = TX_OUTPUT_POWER    ; 
+    ptr_int = (char*) &RF_FREQUENCY     ; for (int i = 0 ; i<4 ; i++)  frameMISNET[10+i] = ptr_int[i] ; 
+    ptr_int = (char*) &valueTimeTx      ; for (int i = 0 ; i<4 ; i++)  frameMISNET[14+i] = ptr_int[i] ;   //printf( "*** LORA ***  TimeTx   %d  %d  ", valueTimeTx, valueTimeLoop);  //delay temps Tx   
+    ptr_int = (char*) &valueTimeLoop    ; for (int i = 0 ; i<4 ; i++)  frameMISNET[18+i] = ptr_int[i] ;   //delay temps Loop  
+    frameMISNET[22] = RssiValue ; 
+    
+    memcpy                      ( Buffer    , frameMISNET   , 23    );
+    
+    valueTimeTx   =  0 ; 
+    valueTimeLoop =  0 ; 
+    timerRadio.reset        ()  ;    // Record tile for close loop
+    timerRadio.start        ()  ; 
+    setRadioTx              ()  ; 
+    TxLed           =       1   ;
+    PacketParams.Params.LoRa.PayloadLength          =   23         ;
+    Radio.SetPacketParams                           ( &PacketParams )           ;
+    Radio.SendPayload       ( Buffer    , 23,( TickTime_t ) {RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE} );
+    TxLed           =       0   ;
+
+    //printf( "*** LORA ***  ARM watchDogRxRxRxRx  \r\n" );
+    watchDogRx.attach (&watchDogRxCRNoReceived, 1.0);     // Arm watchDogRx  if the response is not received in less 500 ms =>  force retry   
+}
+//===============================================================================================================================
+
+
+// Time out si pas de message de CR recu
+void        watchDogRxCRNoReceived ()  { 
+    printf( "*** LORA ***  watchDogRxNoReceive NO RESPONSE    \r\n");    
+}   // Force new emission 
+
+
+
+
+//===============================================================================================================================
+void initRadio () {
+//===============================================================================================================================
+    F_CS   = 1  ;
+    SD_CS  = 1  ;
+    ANT_SW = 1  ;
+    
+    // SET MODULATION
+    modulationParams.PacketType                     =   PACKET_TYPE_LORA        ;
+    modulationParams.Params.LoRa.CodingRate         =   LORA_CR_4_5             ;
+    modulationParams.Params.LoRa.Bandwidth          =   LORA_BW_0200            ; 
+    modulationParams.Params.LoRa.SpreadingFactor    =   LORA_SF7                ; 
+    // SET PACKET PARAM
+    PacketParams.PacketType                         =   PACKET_TYPE_LORA        ;
+    PacketParams.Params.LoRa.PreambleLength         =   0x08                    ;
+    PacketParams.Params.LoRa.HeaderType             =   LORA_PACKET_VARIABLE_LENGTH;
+    PacketParams.Params.LoRa.PayloadLength          =   BUFFER_SIZE_MAX         ;
+    PacketParams.Params.LoRa.CrcMode                =   LORA_CRC_ON             ;
+    PacketParams.Params.LoRa.InvertIQ               =   LORA_IQ_INVERTED        ;
+    // RADIO
+    Radio.SetStandby                                ( STDBY_RC  )               ;
+    Radio.SetPacketType                             ( modulationParams.PacketType );
+    Radio.SetModulationParams                       ( &modulationParams )       ;
+    Radio.SetPacketParams                           ( &PacketParams )           ;   
+    Radio.SetBufferBaseAddresses                    ( 0x00, 0x00 );
+    Radio.SetTxParams                               ( TX_OUTPUT_POWER, RADIO_RAMP_20_US )       ;
+    Radio.SetRx                                     ( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } )   ;
+    //AppState                    =                   APP_LOWPOWER;
+}
+//===============================================================================================================================
+
+
+
+//===============================================================================================================================
+void setRadioTx () {
+//=============================================================================================================================== 
+    RxLed  = 0  ;
+    TxLed  = 0  ;
+    F_CS   = 1  ;
+    SD_CS  = 1  ;
+    ANT_SW = 1  ;
+
+    // SET MODULATION
+    modulationParams.PacketType                     =   PACKET_TYPE_LORA        ;
+    modulationParams.Params.LoRa.CodingRate         =   LORA_CR_4_5             ;
+    modulationParams.Params.LoRa.Bandwidth          =   LORA_BW    ; 
+    modulationParams.Params.LoRa.SpreadingFactor    =   LORA_SF    ; 
+
+    // SET PACKET PARAM
+    PacketParams.PacketType                         =   PACKET_TYPE_LORA        ;
+    PacketParams.Params.LoRa.PreambleLength         =   0x08                    ;
+    PacketParams.Params.LoRa.HeaderType             =   LORA_PACKET_VARIABLE_LENGTH;
+    PacketParams.Params.LoRa.PayloadLength          =   BUFFER_SIZE_MAX         ;
+    PacketParams.Params.LoRa.CrcMode                =   LORA_CRC_ON             ;
+    PacketParams.Params.LoRa.InvertIQ               =   LORA_IQ_INVERTED        ;
+
+    // RADIO
+    Radio.SetStandby                                ( STDBY_RC  )               ;
+    Radio.SetPacketType                             ( modulationParams.PacketType );
+    Radio.SetModulationParams                       ( &modulationParams )       ;
+    Radio.SetPacketParams                           ( &PacketParams )           ;
+    Radio.SetRfFrequency                            ( RF_FREQUENCY )            ;
+    Radio.SetBufferBaseAddresses                    ( 0x00, 0x00 );
+    Radio.SetTxParams                               ( TX_OUTPUT_POWER, RADIO_RAMP_20_US )       ;
+    Radio.SetDioIrqParams                           ( TxIrqMask , TxIrqMask , IRQ_RADIO_NONE, IRQ_RADIO_NONE );
+    Radio.SetRx                                     ( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } )   ;
+
+    //AppState                    =                   APP_LOWPOWER;
+ 
+ }
+
+
+//===============================================================================================================================
+void setRadioRx () {
+//===============================================================================================================================
+    RxLed  = 0  ;
+    TxLed  = 0  ;   
+     // SET MODULATION
+    modulationParams.PacketType                     =   PACKET_TYPE_LORA        ;
+    modulationParams.Params.LoRa.CodingRate         =   LORA_CR_4_5             ;
+    modulationParams.Params.LoRa.Bandwidth          =   LORA_BW_0200            ; 
+    modulationParams.Params.LoRa.SpreadingFactor    =   LORA_SF7                ; 
+
+    // SET PACKET PARAM
+    PacketParams.PacketType                         =   PACKET_TYPE_LORA        ;
+    PacketParams.Params.LoRa.PreambleLength         =   0x08                    ;
+    PacketParams.Params.LoRa.HeaderType             =   LORA_PACKET_VARIABLE_LENGTH;
+    PacketParams.Params.LoRa.PayloadLength          =   BUFFER_SIZE_MIN         ;
+    PacketParams.Params.LoRa.CrcMode                =   LORA_CRC_ON             ;
+    PacketParams.Params.LoRa.InvertIQ               =   LORA_IQ_INVERTED        ;
+
+    // RADIO
+    Radio.SetStandby                                ( STDBY_RC  )               ;
+    Radio.SetPacketType                             ( modulationParams.PacketType );
+    Radio.SetModulationParams                       ( &modulationParams )       ;
+    Radio.SetPacketParams                           ( &PacketParams )           ;
+    Radio.SetRfFrequency                            ( RF_FREQUENCY + 440000UL)            ;
+
+    Radio.SetBufferBaseAddresses                    ( 0x00, 0x00 );
+    Radio.SetTxParams                               ( TX_OUTPUT_POWER, RADIO_RAMP_20_US )       ;
+    Radio.SetDioIrqParams                           ( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE )    ;
+    Radio.SetRx                                     ( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } )   ;
+    //AppState                    =                   APP_LOWPOWER;
+}
+//===============================================================================================================================
+
+
+
+
+// ============================================================================ RADIO CALLBACK
+void OnTxDone       ( void ) {
+//==============================================================================
+    valueTimeTx = timerRadio.read_ms () ; 
+    printf( "*** LORA ***  OnTxDone \r\n" );
+    TxLed   = 0 ;
+    setRadioRx () ; 
+}
+//==============================================================================
+
+
+
+//void OnRxDone       ( void )                          { AppState = APP_RX         ;   }
+//==============================================================================
+void OnRxDone       ( void ) {
+//==============================================================================
+    uint8_t Buffer1 [BUFFER_SIZE_MAX+1];                  // Buffer Radio
+    uint8_t BufferSize = BUFFER_SIZE_MAX ;          // Size of the buffer
+ 
+    RxLed               =   1   ;  // Show the reception 
+
+    printf( "*** LORA ***  RX DONE \r\n" );
+    valueTimeLoop = timerRadio.read_ms ()   ; 
+    timerRadio.stop       ()  ; 
+    watchDogRx.detach     ()  ;      
+    //printf( "*** LORA ***  DISARM watchDogRx  \r\n" );
+
+    Radio.GetPacketStatus(&packetStatus)    ; 
+    RssiValue = packetStatus.LoRa.RssiPkt   ; 
+    
+    memset              ( &Buffer1 , 0x00, BUFFER_SIZE_MAX );
+    Radio.GetPayload    ( Buffer1, &BufferSize, BUFFER_SIZE_MAX );
+    
+    Buffer1[7] = 0 ; 
+
+    printf  ( "*** LORA *** RX DONE =>  %s \r\n", Buffer1 );   wait(1) ; // flush serial 
+     
+    // Extract value 
+    
+    switch (Buffer1[2]) {
+        case '1': RF_FREQUENCY    =   2400000000UL ; break ; 
+        case '2': RF_FREQUENCY    =   2400680000UL ; break ; 
+        case '3': RF_FREQUENCY    =   2423840000UL ; break ; 
+        case '4': RF_FREQUENCY    =   2424520000UL ; break ; 
+        case '5': RF_FREQUENCY    =   2448840000UL ; break ; 
+        case '6': RF_FREQUENCY    =   2449520000UL ; break ; 
+        case '7': RF_FREQUENCY    =   2473840000UL ; break ; 
+        case '8': RF_FREQUENCY    =   2474520000UL ; break ; 
+    }  
+                
+    switch (Buffer1[3]) {
+        case '1': LORA_BW           =   LORA_BW_0200     ;   break ; 
+        case '2': LORA_BW           =   LORA_BW_0400     ;   break ; 
+        case '3': LORA_BW           =   LORA_BW_0800     ;   break ; 
+        case '4': LORA_BW           =   LORA_BW_1600    ;   break ; 
+    }  
+               
+    switch (Buffer1[4]) {
+       case '1': TX_OUTPUT_POWER    =   -18         ;   break   ; 
+       case '2': TX_OUTPUT_POWER    =   0           ;   break   ; 
+       case '3': TX_OUTPUT_POWER    =   8           ;   break   ; 
+       case '4': TX_OUTPUT_POWER    =   10          ;   break   ; 
+       case '5': TX_OUTPUT_POWER    =   13          ;   break   ; 
+    }  
+                               
+    switch (Buffer1[5]) {
+       case '1': LORA_SF            =   LORA_SF5       ;   break     ; 
+       case '2': LORA_SF            =   LORA_SF6       ;   break     ; 
+       case '3': LORA_SF            =   LORA_SF7       ;   break     ; 
+       case '4': LORA_SF            =   LORA_SF8       ;   break     ; 
+       case '5': LORA_SF            =   LORA_SF9       ;   break     ; 
+       case '6': LORA_SF            =   LORA_SF10      ;   break     ; 
+       case '7': LORA_SF            =   LORA_SF12      ;   break     ; 
+    }  
+
+   int OLD_TIMER = TIMER ; 
+   
+   switch (Buffer1[6]) {
+        case '1': TIMER      =   50     ;   break     ; 
+        case '2': TIMER      =   75     ;   break     ; 
+        case '3': TIMER      =   125    ;   break     ; 
+        case '4': TIMER      =   250    ;   break     ; 
+        case '5': TIMER      =   500    ;   break     ; 
+        case '6': TIMER      =   1000   ;   break     ; 
+        case '7': TIMER      =   2000   ;   break     ; 
+     }    
+
+    RxLed               =   0             ;
+
+    if (oldFreq != Buffer1[2] || oldBw   != Buffer1[3] || oldPwr  != Buffer1[4] || oldSf   != Buffer1[5] || oldTimer   != Buffer1[6] ) {
+            oldFreq = Buffer1[2] ;
+            oldBw   = Buffer1[3] ;
+            oldPwr  = Buffer1[4] ;
+            oldSf   = Buffer1[5] ; 
+            oldTimer = Buffer1[6] ;
+            //printf  ( "*** LORA *** Reset Radio \r\n" );
+            //app.updateDisplay   ( LORA_SF, LORA_BW, TX_OUTPUT_POWER, BUFFER_SIZE_MAX, RF_FREQUENCY, TIMER ) ; 
+    }   
+    
+    if (OLD_TIMER != TIMER) {
+        //wakeUpTerminal.detach   ();
+        //wakeUpTerminal.attach   (&wakeUpTerminalFunction, (float) TIMER/1000);
+    }
+}
+//==============================================================================
+
+void OnTxTimeout    ( void )                        { AppState = APP_TX_TIMEOUT ;}
+void OnRxTimeout    ( void )                        { AppState = APP_RX_TIMEOUT ; }
+void OnRxError      ( IrqErrorCode_t errorCode )    { AppState = APP_RX_ERROR   ; }
+void OnRangingDone  ( IrqRangingCode_t val )        {  }
+void OnCadDone      ( bool channelActivityDetected ){  }
+
+