1 // ********************************************************************* 2 // Custom DPA Handler - Beaming example * 3 // ********************************************************************* 4 // Copyright (c) MICRORISC s.r.o. 5 // 6 // File: $RCSfile: CustomDpaHandler-SensorBeaming.c,v $ 7 // Version: $Revision: 1.11 $ 8 // Date: $Date: 2021/05/07 11:09:28 $ 9 // 10 // Revision history: 11 // 2020/09/03 Release for DPA 4.15 12 // 13 // ********************************************************************* 14 15 // Online DPA documentation https://doc.iqrf.org/DpaTechGuide/ 16 17 /* 18 * This is public example of the beaming sensor code. 19 * The actual beamed quantities' values are fake. Please see the code below. 20 * After the button is pressed for a longer time the LEDR pulses and data are beamed. The device then goes to sleep. 21 * The device wakes up by pressing the button which is indicated by LEDG pulse. 22 */ 23 24 // Default IQRF include (modify the path according to your setup) 25 #include "IQRF.h" 26 27 // Default DPA header (modify the path according to your setup) 28 #include "DPA.h" 29 // Default Custom DPA Handler header (modify the path according to your setup) 30 #include "DPAcustomHandler.h" 31 // IQRF standards header (modify the path according to your setup) 32 #include "standard/IQRFstandard.h" 33 #include "standard/IQRF_HWPID.h" 34 35 // This HWPID 36 #define _HWPID_ 0x123F 37 38 // Define to return sensors in error 39 //#define SENSOR_ERRORS 40 41 // Must be the 1st defined function in the source code in order to be placed at the correct FLASH location! 42 //############################################################################################ 43 bit CustomDpaHandler() 44 //############################################################################################ 45 { 46 #pragma updateBank default = UserBank_01 47 48 // Handler presence mark 49 clrwdt(); 50 51 // Detect DPA event to handle (unused event handlers can be commented out or even deleted) 52 switch ( GetDpaEvent() ) 53 { 54 // ------------------------------------------------- 55 case DpaEvent_Interrupt: 56 // Do an extra quick background interrupt work 57 return Carry; 58 59 // ------------------------------------------------- 60 case DpaEvent_Idle: 61 // Do a quick background work when RF packet is not received 62 63 { 64 // To detect long button press 65 static uns8 buttonCnt; 66 67 if ( !buttonPressed ) 68 buttonCnt = 0; 69 else 70 { 71 // Note: when run at LP mode, than the press time must be adjusted for shorter counts that even depends on LPtoutRF value 72 if ( ++buttonCnt == 0 ) 73 { 74 // Indicate button was pressed for the longer time and then wait for its release 75 setLEDR(); 76 do 77 { 78 clrwdt(); 79 } while ( buttonPressed ); 80 stopLEDR(); 81 82 // Prepare off-line sensor packet 83 84 // No DPA Params used 85 _DpaParams = 0; 86 87 // Beaming is broadcast (could be unicast too) 88 _NADR = BROADCAST_ADDRESS; 89 _NADRhigh = 0; 90 91 // Prepare sensor packet type and quantity data 92 93 _PNUM = PNUM_STD_SENSORS; 94 _PCMD = PCMD_STD_SENSORS_READ_TYPES_AND_FRC_VALUES | RESPONSE_FLAG; 95 // HW profile ID 96 _HWPID = _HWPID_; 97 98 { // 1st sensor/quantity 99 // Fake "living" temperature value = NodeAddress + [0-15]/16; 100 _DpaMessage.Request.PData[0] = STD_SENSOR_TYPE_TEMPERATURE; 101 shadowDef uns16 temperature @ ( &_DpaMessage.Request.PData[1] ); 102 #ifndef SENSOR_ERRORS 103 temperature = (uns16)ntwADDR * 16; 104 temperature |= ( Random.low8 & ( 16 - 1 ) ); 105 temperature |= 0x8000; 106 #else 107 temperature = FRC_STD_FRC_ERROR_VALUE; 108 #endif 109 // Length of the data inside DPA Request message 110 _DpaDataLength = sizeof( uns8 ) + sizeof( uns16 ); 111 } 112 113 { // Optional 2nd sensor/quantity 114 // Fake "living" humidity value = NodeAddress + [0-1]/2; 115 _DpaMessage.Request.PData[3] = STD_SENSOR_TYPE_HUMIDITY; 116 #ifndef SENSOR_ERRORS 117 _DpaMessage.Request.PData[4] = 4 + ( ntwADDR & 0x3F ) * 2; 118 _DpaMessage.Request.PData[4] |= Random.high8 & 0x01; 119 #else 120 _DpaMessage.Request.PData[4] = FRC_STD_FRC_ERROR_VALUE; 121 #endif 122 // Length of the data inside DPA Request message 123 _DpaDataLength += sizeof( uns8 ) + sizeof( uns8 ); 124 } 125 126 { // Optional 3rd sensor/quantity 127 // Fake CO2 value 128 _DpaMessage.Request.PData[5] = STD_SENSOR_TYPE_CO2; 129 shadowDef uns16 co2 @ ( &_DpaMessage.Request.PData[6] ); 130 #ifndef SENSOR_ERRORS 131 co2 = 2345 + 4; 132 #else 133 co2 = FRC_STD_FRC_ERROR_VALUE; 134 #endif 135 // Length of the data inside DPA Request message 136 _DpaDataLength += sizeof( uns8 ) + sizeof( uns16 ); 137 } 138 139 { // Optional 4th sensor/quantity 140 // Fake Binary30 141 _DpaMessage.Request.PData[8] = STD_SENSOR_TYPE_BINARYDATA30; 142 shadowDef uns32 bin30 @ ( &_DpaMessage.Request.PData[9] ); 143 #ifndef SENSOR_ERRORS 144 #if !defined( __CC5XFREE__ ) // CC5X free edition does not support 32bit assignment 145 bin30 = 0x3456789A + 4; 146 #else 147 bin30.low16 = ( 0x3456789A + 4 ) & 0xFfFf; 148 bin30.high16 = ( 0x3456789A + 4 ) >> 16; 149 #endif 150 #else 151 #if !defined( __CC5XFREE__ ) // CC5X free edition does not support 32bit assignment 152 bin30 = FRC_STD_FRC_ERROR_VALUE; 153 #else 154 bin30.low16 = FRC_STD_FRC_ERROR_VALUE; 155 bin30.high16 = 0; 156 #endif 157 #endif 158 // Length of the data inside DPA Request message 159 _DpaDataLength += sizeof( uns8 ) + sizeof( uns32 ); 160 } 161 162 { // Optional 5th sensor/quantity 163 // Fake Binary7 164 _DpaMessage.Request.PData[13] = STD_SENSOR_TYPE_BINARYDATA7; 165 #ifndef SENSOR_ERRORS 166 _DpaMessage.Request.PData[14] = ( ntwADDR & 0x7F ) + 4; 167 #else 168 _DpaMessage.Request.PData[14] = FRC_STD_FRC_ERROR_VALUE; 169 #endif 170 // Length of the data inside DPA Request message 171 _DpaDataLength += sizeof( uns8 ) + sizeof( uns8 ); 172 } 173 174 // Do simplified LBT 175 uns8 loop = 3; 176 do 177 { 178 if ( !checkRF( DpaApiReadConfigByte( CFGIND_RXFILTER ) + 10 ) ) 179 break; 180 181 // Do some wait (better to do a random time sleep) 182 waitMS( 5 ); 183 } while ( --loop != 0 ); 184 185 // Force not routed packet to be sent from N by DPA API 186 NonroutedRfTxDpaPacket = TRUE; 187 188 // TX DPA message with zero DPA Value and asynchronous 189 // Note: Use DpaValue = 0x01 to indicate asynchronous i.e. non-regular beaming 190 DpaApiRfTxDpaPacket( 0 /*DpaValue*/, 0 ); 191 192 // Now go to endless sleep with a button wakeup 193 _PNUM = PNUM_OS; 194 _PCMD = CMD_OS_SLEEP; 195 _DpaDataLength = sizeof( _DpaMessage.PerOSSleep_Request ); 196 // Wake up on PIN change, LEDG flash after wake up 197 _DpaMessage.PerOSSleep_Request.Time = 0x0000; 198 _DpaMessage.PerOSSleep_Request.Control = 0b101; 199 // Perform local DPA Request 200 DpaApiLocalRequest(); 201 } 202 } 203 } 204 break; 205 206 // ------------------------------------------------- 207 case DpaEvent_DpaRequest: 208 // Called to interpret DPA request for peripherals 209 if ( IsDpaEnumPeripheralsRequest() ) 210 { 211 // ------------------------------------------------- 212 // Peripheral enumeration 213 _DpaMessage.EnumPeripheralsAnswer.HWPID |= _HWPID_; 214 _DpaMessage.EnumPeripheralsAnswer.HWPIDver |= 0; 215 216 DpaHandleReturnTRUE: 217 return TRUE; 218 } 219 220 break; 221 } 222 223 DpaHandleReturnFALSE: 224 return FALSE; 225 } 226 227 //############################################################################################ 228 // 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) 229 #include "DPAcustomHandler.h" 230 //############################################################################################