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