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