1 // ********************************************************************* 2 // Main Custom DPA Handler header * 3 // ********************************************************************* 4 // Copyright (c) MICRORISC s.r.o. 5 // 6 // File: $RCSfile: DPAcustomHandler.h,v $ 7 // Version: $Revision: 1.160 $ 8 // Date: $Date: 2023/03/07 08:03:13 $ 9 // 10 // Revision history: 11 // 2023/03/07 Release for DPA 4.30 12 // 2022/10/05 Release for DPA 4.18 13 // 2022/02/24 Release for DPA 4.17 14 // 2021/08/20 Release for DPA 4.16 15 // 2020/09/03 Release for DPA 4.15 16 // 2020/04/03 Release for DPA 4.14 17 // 2020/02/27 Release for DPA 4.13 18 // 2020/01/09 Release for DPA 4.12 19 // 2019/12/11 Release for DPA 4.11 20 // 2019/10/09 Release for DPA 4.10 21 // 2019/06/12 Release for DPA 4.03 22 // 2019/06/03 Release for DPA 4.02 23 // 2019/03/07 Release for DPA 4.01 24 // 2019/01/10 Release for DPA 4.00 25 // 2018/10/25 Release for DPA 3.03 26 // 2017/11/16 Release for DPA 3.02 27 // 2017/08/14 Release for DPA 3.01 28 // 2017/03/13 Release for DPA 3.00 29 // 2016/09/12 Release for DPA 2.28 30 // 2016/04/14 Release for DPA 2.27 31 // 2016/03/03 Release for DPA 2.26 32 // 2016/01/21 Release for DPA 2.25 33 // 2015/12/01 Release for DPA 2.24 34 // 2015/10/23 Release for DPA 2.23 35 // 2015/09/25 Release for DPA 2.22 36 // 2015/09/03 Release for DPA 2.21 37 // 2015/08/05 Release for DPA 2.20 38 // 2014/10/31 Release for DPA 2.10 39 // 2014/04/30 Release for DPA 2.00 40 // 2013/10/03 Release for DPA 1.00 41 // 42 // ********************************************************************* 43 44 // Online DPA documentation https://doc.iqrf.org/DpaTechGuide/ 45 // IQRF Standards documentation https://doc.iqrf.org/ 46 47 #ifndef _CUSTOM_DPA_HANDLER_ 48 #define _CUSTOM_DPA_HANDLER_ 49 50 //############################################################################################ 51 // 1st include 52 53 // Custom DPA Handler routine declaration 54 bit CustomDpaHandler(); 55 56 // Various DPA flags shared between DPA and Custom DPA Handler 57 uns8 DpaFlags @ usedBank4[0]; 58 59 // [C][N] TRUE if I2C timeout occurred at the last DpaApiI2C?() call 60 bit I2CwasTimeout @ DpaFlags.0; 61 // [N] Flag for the 1st DpaApiSleep 62 bit FirstDpaApiSleep @ DpaFlags.1; 63 64 #ifdef COORDINATOR_CUSTOM_HANDLER 65 // [C] TRUE if interface master is not connected (detected) 66 bit IFaceMasterNotConnected @ DpaFlags.2; 67 #endif 68 // [N] DPA by interface notification is sent also when there was a "reading" like DPA request 69 bit EnableIFaceNotificationOnRead @ DpaFlags.3; 70 // [N] TRUE when node was just bonded using default bonding procedure 71 bit NodeWasBonded @ DpaFlags.4; 72 // [N] When TRUE, then next call of DpaApiRfTxDpaPacket sends non-routed packet 73 bit NonroutedRfTxDpaPacket @ DpaFlags.7; 74 75 // [C] Ticks (decrementing) counter usable for timing in the coordinator's Customer DPA Handler 76 uns16 DpaTicks @ usedBank4[1]; 77 // [N] toutRF for LP mode, read from configuration memory after reset 78 uns8 LPtoutRF @ usedBank4[3]; 79 // DPA Request/Response HWPID 80 uns16 _HWPID @ usedBank4[4]; 81 // Identifies type of reset (stored at UserReg0 upon module reset). See Reset chapter at IQRF User's Guide for more information 82 uns8 ResetType @ usedBank4[6]; 83 // User DPA Values to return 84 uns8 UserDpaValue @ usedBank4[7]; 85 // Network depth of the DPA request/response, increases on bridging, decreases on back-bridging 86 uns8 NetDepth @ usedBank4[8]; 87 // TRUE when node was at DPA Service Mode after last boot 88 bit DSMactivated @ usedBank4[9].0; 89 // If set to TRUE, then LP RX mode in the main loop can be terminated by pin, see _RLPMAT 90 bit LpRxPinTerminate @ usedBank4[9].1; 91 // If set to TRUE, then [C] executes asynchronous DPA requests received from [N] 92 bit AsyncReqAtCoordinator @ usedBank4[9].2; 93 // RX filter used at the DPA main loop checkRF call 94 uns8 RxFilter @ usedBank4[11]; 95 // Countdown variable for button bonding before going to deep sleep 96 uns16 BondingSleepCountdown @ usedBank4[12]; 97 #define BONDING_SLEEP_COUNTDOWN_UNIT 290 98 // Non-zero pseudo-random value, read-only, updated on every Reset and Idle event, at [N] only. 99 uns16 Random @ usedBank4[14]; 100 // DPA value from the received packet or just to be sent to the interface. 101 uns8 DpaValue @ usedBank4[16]; 102 // If non-zero then timeout value for DpaApiI2C?() calls 103 uns8 I2Ctimeout @ usedBank4[17]; 104 105 // Macro to return an error from the peripheral handler. If the code size is not an issue this macro is the right choice. 106 #define DpaApiReturnPeripheralError(error) do { \ 107 DpaApiSetPeripheralError( error ); \ 108 return Carry; \ 109 } while( 0 ) 110 111 // DPA API functions, see documentation for details 112 #define DpaApiRfTxDpaPacket( dpaValue, netDepthAndFlags ) DpaApiEntry( dpaValue, netDepthAndFlags, DPA_API_RFTX_DPAPACKET ) 113 #define DpaApiReadConfigByte( index ) DpaApiEntry( index, param3.low8, DPA_API_READ_CONFIG_BYTE ) 114 #define DpaApiLocalRequest() DpaApiEntry( param2, param3.low8, DPA_API_LOCAL_REQUEST ) 115 #define DpaApiSetPeripheralError( error ) DpaApiEntry( error, param3.low8, DPA_API_SET_PERIPHERAL_ERROR ) 116 #define DpaApiSendToIFaceMaster( dpaValue, flags ) DpaApiEntry( dpaValue, flags, DPA_API_SEND_TO_IFACEMASTER ) 117 #define DpaApiSetRfDefaults() DpaApiEntry( param2, param3.low8, DPA_API_SET_RF_DEFAULTS ) 118 #define DpaApiLocalFrc( frcCommand, replyTxPower ) DpaApiEntry( frcCommand, replyTxPower, DPA_API_LOCAL_FRC ) 119 #define DpaApiCrc8( crc8, data ) DpaApiEntry( crc8, data, DPA_API_CRC8 ) 120 #define DpaApiAggregateFrc() DpaApiEntry( param2, param3.low8, DPA_API_AGGREGATE_FRC ) 121 #define DpaApiSetOTK() DpaApiEntry( param2, param3.low8, DPA_API_SET_OTK ) 122 #define DpaApiI2Cinit( frequency ) DpaApiEntry( frequency, param3.low8, DPA_API_I2C_INIT ) 123 #define DpaApiI2Cstart( address ) DpaApiEntry( address, param3.low8, DPA_API_I2C_START ) 124 #define DpaApiI2Cwrite( data ) DpaApiEntry( data, param3.low8, DPA_API_I2C_WRITE ) 125 #define DpaApiI2Cread( ack ) DpaApiEntry( ack, param3.low8, DPA_API_I2C_READ ) 126 #define DpaApiI2Cstop() DpaApiEntry( param2, param3.low8, DPA_API_I2C_STOP ) 127 #define DpaApiI2CwaitForACK( address ) DpaApiEntry( address, param3.low8, DPA_API_I2C_WAIT_FOR_ACK ) 128 #define DpaApiI2Cshutdown() DpaApiEntry( param2, param3.low8, DPA_API_I2C_SHUTDOWN ) 129 #define DpaApiI2CwaitForIdle() DpaApiEntry( param2, param3.low8, DPA_API_I2C_WAIT_FOR_IDLE ) 130 #define DpaApiSleep( wdtcon ) DpaApiEntry( wdtcon, param3.low8, DPA_API_SLEEP ) 131 #define DpaApiAfterSleep() DpaApiEntry( param2, param3.low8, DPA_API_AFTER_SLEEP ) 132 #define DpaApiRandom() DpaApiEntry( param2, param3.low8, DPA_API_RANDOM ) 133 134 #ifdef COORDINATOR_CUSTOM_HANDLER 135 #define DpaApiRfTxDpaPacketCoordinator() DpaApiEntry( param2, param3.low8, DPA_API_COORDINATOR_RFTX_DPAPACKET ) 136 #endif 137 138 #if !defined( TR7xD ) 139 #define DpaApiMenu( menu, flags ) DpaApiEntry( menu, flags, DPA_API_MENU ) 140 #define DpaApiMenuIndicateResult( ok ) DpaApiEntry( ok, param3.low8, DPA_API_MENU_INDICATE_RESULT ) 141 #define DpaApiMenuExecute( menuAndItem ) DpaApiEntry( menuAndItem, param3.low8, DPA_API_MENU_EXECUTE ) 142 #define DpaApiDeepSleep( wdtcon ) DpaApiEntry( wdtcon, param3.low8, DPA_API_DEEP_SLEEP ) 143 #endif 144 145 #define DpaApiLocalFrc_StackSaver( frcCommand, replyTxPower ) \ 146 param2 = frcCommand; \ 147 param3.low8 = replyTxPower; \ 148 W = DPA_API_LOCAL_FRC; \ 149 #asm \ 150 DW __MOVLP( DPA_API_ADDRESS >> 8 ); \ 151 DW __CALL( DPA_API_ADDRESS ); \ 152 DW __MOVLP( CUSTOM_HANDLER_ADDRESS >> 8 ); \ 153 #endasm \ 154 155 #define I2CcomputeFrequency( I2Cfrequency) ( ( ( F_OSC ) / ( ( I2Cfrequency ) * 4 ) ) - 1 ) 156 157 // Wrapper routines to be called instead of DpaApi??? macros to decrease code size if more than ~2 calls are needed 158 void _DpaApiI2Cinit( uns8 frequency ); 159 void _DpaApiI2Cstart( uns8 address ); 160 void _DpaApiI2Cwrite( uns8 data ); 161 uns8 _DpaApiI2Cread( uns8 ack ); 162 void _DpaApiI2Cstop(); 163 void _DpaApiI2CwaitForACK( uns8 address ); 164 void _DpaApiI2Cshutdown(); 165 void _DpaApiI2CwaitForIdle(); 166 void _DpaApiSleep( uns8 wdtcon ); 167 void _DpaApiSleepFirst( uns8 wdtcon ); 168 void _DpaApiAfterSleep(); 169 uns8 _DpaApiRandom(); 170 void _DpaApiSetRfDefaults(); 171 172 // Helper "multi" function to decrease code size if used more times 173 void _DpaApiI2Cwrite0(); 174 void _DpaApiI2CwriteAndStop( uns8 data ); 175 uns8 _DpaApiI2CreadACK(); 176 uns8 _DpaApiI2CreadNACK(); 177 uns8 _DpaApiI2CreadNACKandStop(); 178 179 #ifdef COORDINATOR_CUSTOM_HANDLER 180 #undef DpaEvent_Interrupt 181 #undef DpaEvent_BeforeSleep 182 #undef DpaEvent_AfterSleep 183 #undef DpaEvent_FrcValue 184 #undef DpaEvent_FrcResponseTime 185 #else 186 #undef DpaEvent_ReceiveDpaResponse 187 #undef DpaEvent_IFaceReceive 188 #endif 189 190 // To detect overlapping code in case someone would put some code before this header by mistake 191 #pragma origin __APPLICATION_ADDRESS 192 #pragma updateBank 0 193 194 //############################################################################################ 195 // Main IQRF entry point jumps to the main DPA entry point 196 void APPLICATION() 197 //############################################################################################ 198 { 199 #asm 200 DW __MOVLP( MAIN_DPA_ADDRESS >> 8 ); 201 DW __GOTO( MAIN_DPA_ADDRESS ); 202 #endasm 203 204 #ifndef NO_CUSTOM_DPA_HANDLER 205 // Fake call to force CustomDpaHandler() compilation 206 CustomDpaHandler(); 207 #endif 208 209 // Fake call to force DpaApiEntry() compilation 210 DpaApiEntry( param2, param3.low8, W ); 211 } 212 213 //############################################################################################ 214 // Entry stub to the real DPA API entry 215 #pragma origin DPA_API_ADDRESS_ENTRY 216 uns8 DpaApiEntry( uns8 par1 @ param2, uns8 par2 @ param3.low8, uns8 apiIndex @ W ) 217 //############################################################################################ 218 { 219 #asm 220 DW __MOVLP( DPA_API_ADDRESS >> 8 ); 221 DW __CALL( DPA_API_ADDRESS ); 222 DW __MOVLP( DPA_API_ADDRESS_ENTRY >> 8 ); 223 #endasm 224 225 return W; 226 } 227 228 //############################################################################################ 229 #pragma origin DPA_API_ADDRESS_ENTRY + 0x08 230 231 //############################################################################################ 232 233 #ifndef NO_CUSTOM_DPA_HANDLER 234 // Next comes Custom DPA handler routine 235 #pragma origin CUSTOM_HANDLER_ADDRESS 236 #endif 237 238 #pragma updateBank 1 239 240 //############################################################################################ 241 #else // _CUSTOM_DPA_HANDLER_ 242 //############################################################################################ 243 // 2nd include 244 245 #ifndef NO_CUSTOM_DPA_HANDLER 246 247 // Library wrappers and helpers to decrease code size 248 //############################################################################################ 249 #pragma library 1 250 //############################################################################################ 251 uns8 _DpaApiUserBank_01( uns8 apiIndex @ W ) 252 //############################################################################################ 253 { 254 #pragma updateBank exit = UserBank_01 255 return DpaApiEntry( param2, param3.low8, apiIndex ); 256 } 257 //############################################################################################ 258 void _DpaApiI2Cinit( uns8 frequency @ W ) 259 //############################################################################################ 260 { 261 #pragma updateBank exit = UserBank_01 262 param2 = frequency; 263 _DpaApiUserBank_01( DPA_API_I2C_INIT ); 264 } 265 //############################################################################################ 266 void _DpaApiI2Cstart( uns8 address @ W ) 267 //############################################################################################ 268 { 269 #pragma updateBank exit = UserBank_01 270 param2 = address; 271 _DpaApiUserBank_01( DPA_API_I2C_START ); 272 } 273 //############################################################################################ 274 void _DpaApiI2Cwrite0() 275 //############################################################################################ 276 { 277 #pragma updateBank exit = UserBank_01 278 _DpaApiI2Cwrite( 0 ); 279 } 280 //############################################################################################ 281 void _DpaApiI2Cwrite( uns8 data @ W ) 282 //############################################################################################ 283 { 284 #pragma updateBank exit = UserBank_01 285 param2 = data; 286 _DpaApiUserBank_01( DPA_API_I2C_WRITE ); 287 } 288 //############################################################################################ 289 uns8 _DpaApiI2CreadNACKandStop() 290 //############################################################################################ 291 { 292 #pragma updateBank exit = UserBank_01 293 param2 = _DpaApiI2CreadNACK(); 294 _DpaApiI2Cstop(); /* Must not use param2 */ 295 return param2; 296 } 297 //############################################################################################ 298 uns8 _DpaApiI2CreadACK() 299 //############################################################################################ 300 { 301 #pragma updateBank exit = UserBank_01 302 return _DpaApiI2Cread( 1 ); 303 } 304 //############################################################################################ 305 uns8 _DpaApiI2CreadNACK() 306 //############################################################################################ 307 { 308 #pragma updateBank exit = UserBank_01 309 return _DpaApiI2Cread( 0 ); 310 } 311 //############################################################################################ 312 uns8 _DpaApiI2Cread( uns8 ack @ W ) 313 //############################################################################################ 314 { 315 #pragma updateBank exit = UserBank_01 316 param2 = ack; 317 return _DpaApiUserBank_01( DPA_API_I2C_READ ); 318 } 319 //############################################################################################ 320 void _DpaApiI2CwriteAndStop( uns8 data @ W ) 321 //############################################################################################ 322 { 323 #pragma updateBank exit = UserBank_01 324 _DpaApiI2Cwrite( data ); 325 _DpaApiI2Cstop(); 326 } 327 //############################################################################################ 328 void _DpaApiI2Cstop() 329 //############################################################################################ 330 { 331 #pragma updateBank exit = UserBank_01 332 _DpaApiUserBank_01( DPA_API_I2C_STOP ); 333 } 334 //############################################################################################ 335 void _DpaApiI2CwaitForACK( uns8 address @ W ) 336 //############################################################################################ 337 { 338 #pragma updateBank exit = UserBank_01 339 DpaApiI2CwaitForACK( address ); 340 } 341 //############################################################################################ 342 void _DpaApiI2Cshutdown() 343 //############################################################################################ 344 { 345 #pragma updateBank exit = UserBank_01 346 _DpaApiUserBank_01( DPA_API_I2C_SHUTDOWN ); 347 } 348 //############################################################################################ 349 void _DpaApiI2CwaitForIdle() 350 //############################################################################################ 351 { 352 #pragma updateBank exit = UserBank_01 353 _DpaApiUserBank_01( DPA_API_I2C_WAIT_FOR_IDLE ); 354 } 355 //############################################################################################ 356 void _DpaApiSleep( uns8 wdtcon @ W ) 357 //############################################################################################ 358 { 359 #pragma updateBank exit = UserBank_01 360 param2 = wdtcon; 361 _DpaApiUserBank_01( DPA_API_SLEEP ); 362 } 363 //############################################################################################ 364 void _DpaApiSleepFirst( uns8 wdtcon @ W ) 365 //############################################################################################ 366 { 367 #pragma updateBank exit = UserBank_01 368 FirstDpaApiSleep = TRUE; 369 _DpaApiSleep( wdtcon ); 370 } 371 //############################################################################################ 372 void _DpaApiAfterSleep() 373 //############################################################################################ 374 { 375 #pragma updateBank exit = UserBank_01 376 _DpaApiUserBank_01( DPA_API_AFTER_SLEEP ); 377 } 378 //############################################################################################ 379 uns8 _DpaApiRandom() 380 //############################################################################################ 381 { 382 #pragma updateBank exit = UserBank_01 383 return _DpaApiUserBank_01( DPA_API_RANDOM ); 384 } 385 //############################################################################################ 386 void _DpaApiSetRfDefaults() 387 //############################################################################################ 388 { 389 #pragma updateBank exit = UserBank_01 390 _DpaApiUserBank_01( DPA_API_SET_RF_DEFAULTS ); 391 } 392 //############################################################################################ 393 394 // Code bumper to detect too long code of Custom DPA handler + other routines 395 #pragma origin CUSTOM_HANDLER_ADDRESS_END 396 // To avoid adding some code after handler by mistake 397 #pragma origin __MAX_FLASH_ADDRESS 398 #endif 399 400 #endif // _CUSTOM_DPA_HANDLER_ 401 //############################################################################################