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 //############################################################################################