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 //############################################################################################