1 // *********************************************************************
    2 //   Custom DPA Handler - FRC  aggregation example                     *
    3 // *********************************************************************
    4 // Copyright (c) MICRORISC s.r.o.
    5 //
    6 // File:    $RCSfile: CustomDpaHandler-FrcAggregation.c,v $
    7 // Version: $Revision: 1.13 $
    8 // Date:    $Date: 2021/09/07 14:22:28 $
    9 //
   10 // Revision history:
   11 //   2021/08/20  Release for DPA 4.16
   12 //
   13 // *********************************************************************
   14 
   15 // Online DPA documentation https://doc.iqrf.org/DpaTechGuide/
   16 
   17 /*
   18 * This example shows how to aggregate FRC values in the discovered Node from other Nodes.
   19 * The example handles custom FRC 1 byte command FRC_USER_BYTE_FROM (0xC0) and
   20 * returns FRC values from 0x82 to 0x84 for Nodes #2 to #4 respectively.
   21 * When trying this example, please make sure Nodes #2 to #4 are bonded to the network, but switched off.
   22 * Also this example must be loaded into another but discovered Node, e.g. to the Node #1.
   23 *
   24 * See advance example CustomDpaHandler-BeamingAggregation.c for the beamed IQRF Standard Sensor data aggregation.
   25 */
   26 
   27 // Default IQRF include (modify the path according to your setup)
   28 #include "IQRF.h"
   29 
   30 // Default DPA header (modify the path according to your setup)
   31 #include "DPA.h"
   32 // Default Custom DPA Handler header (modify the path according to your setup)
   33 #include "DPAcustomHandler.h"
   34 
   35 // Must be the 1st defined function in the source code in order to be placed at the correct FLASH location!
   36 //############################################################################################
   37 bit CustomDpaHandler()
   38 //############################################################################################
   39 {
   40 #pragma updateBank default = UserBank_01
   41 
   42   // Handler presence mark
   43   clrwdt();
   44 
   45   // Detect DPA event to handle (unused event handlers can be commented out or even deleted)
   46   switch ( GetDpaEvent() )
   47   {
   48     // -------------------------------------------------
   49     case DpaEvent_Interrupt:
   50       // Do an extra quick background interrupt work
   51       return Carry;
   52 
   53       // -------------------------------------------------
   54     case DpaEvent_FrcValue:
   55       // Called to get FRC value
   56 
   57       // Is this the 1 Byte FRC command we handle?
   58       if ( PCMD == FRC_USER_BYTE_FROM )
   59       {
   60         // Clear the FRC aggregation buffer
   61         clearBufferINFO();
   62         // Set the pointer to the beginning of the aggregation buffer
   63         setFSR0( _FSR_INFO );
   64         // Move pointer to the place for the 1st addressed node
   65         FSR0 += sizeof( uns8 );
   66         // Variable for the "Node" loop
   67         uns8 node = 0;
   68         do {
   69           // Check whether the current node was addressed by FRC.
   70           addressBitmap( ++node );
   71           // Prepare the pointer to beginning of the bitmap of FRC addressed Nodes
   72 #if &bufferRF[0] != &AddressedNodesBeforeResponseFRC[0]
   73           setFSR1( _FSR_RF );   // Optimize
   74 #else
   75           FSR1 = &AddressedNodesBeforeResponseFRC[0];
   76 #endif
   77           // Move the pointer to the bitmap byte, where the bit for the checked node is
   78           FSR1L += bitmapByteIndex; // Note: FSR0L will not overflow
   79           // Is Node addressed by the FRC command? (i.e. is the bit set?)
   80 
   81           // IQRF OS bit indicating selective FRC (bit.0 at the 1st byte behind AddressedNodesBeforeResponseFRC)
   82           bit isSelectiveFrc @ AddressedNodesBeforeResponseFRC[sizeof( AddressedNodesBeforeResponseFRC )].0;
   83           // W = bitmap byte
   84           W = *FSR1;
   85           if ( !isSelectiveFrc )  // Note: must not modify W
   86             W = 0xFF; // Not selective FRC => all nodes are selected
   87           // Is Nodes selected?
   88           if ( ( W & bitmapBitMask ) != 0 )
   89           {
   90             // Is the addressed node one of the Nodes (2-4) we handle in this example?
   91             // If so, store its (fake) aggregated FRC value (0x82-0x84) into the aggregation buffer(INFO).
   92             // Normally the formerly obtained and currently aggregated FRC data will be stored in the (external) memory.
   93             switch ( node )
   94             {
   95               case 2:
   96                 setINDF0( 0x82 );
   97                 break;
   98 
   99               case 3:
  100                 setINDF0( 0x83 );
  101                 break;
  102 
  103               case 4:
  104                 setINDF0( 0x84 );
  105                 break;
  106             }
  107 
  108             // Move pointer to the next FRC value byte in the aggregation buffer
  109             FSR0 += sizeof( uns8 );
  110           }
  111           // Loop until
  112         } while (
  113           // Aggregation buffer is not full/over
  114           FSR0L < ( &bufferINFO[sizeof( bufferINFO )] & 0xFF ) &&
  115           // and not all node addresses were checked
  116           node != MAX_ADDRESS );
  117 
  118         // Start FRC value aggregation.
  119         // Important:
  120         //  This node must be discovered and the feature "FRC Aggregation" must be set from MICRORISC (i.e. the TR transceiver manufacturer)
  121         //  otherwise the aggregation will not work.
  122         DpaApiAggregateFrc();
  123       }
  124       break;
  125 
  126       // -------------------------------------------------
  127     case DpaEvent_FrcResponseTime:
  128       // Called to get FRC response time
  129 
  130       if ( DataOutBeforeResponseFRC[0] == FRC_USER_BYTE_FROM )
  131         responseFRCvalue = _FRC_RESPONSE_TIME_40_MS;
  132 
  133       break;
  134 
  135       // -------------------------------------------------
  136     case DpaEvent_DpaRequest:
  137       // Called to interpret DPA request for peripherals
  138       if ( IsDpaEnumPeripheralsRequest() )
  139       {
  140         // -------------------------------------------------
  141         // Peripheral enumeration
  142         _DpaMessage.EnumPeripheralsAnswer.HWPID |= 0x456F;
  143         return TRUE;
  144       }
  145 
  146       break;
  147   }
  148 
  149   return FALSE;
  150 }
  151 
  152 //############################################################################################
  153 // Default Custom DPA Handler header; 2nd include to implement Code bumper to detect too long code of the Custom DPA Handler (modify the path according to your setup)
  154 #include "DPAcustomHandler.h"
  155 //############################################################################################