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