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