1 // ********************************************************************* 2 // Custom DPA Handler code template * 3 // ********************************************************************* 4 // Copyright (c) MICRORISC s.r.o. 5 // 6 // File: $RCSfile: CustomDpaHandler-TwoButtons.c,v $ 7 // Version: $Revision: 1.2 $ 8 // Date: $Date: 2026/05/22 14:48:54 $ 9 // 10 // Revision history: 11 // 2025/05/30 Release for DPA 4.33 12 // 13 // ********************************************************************* 14 15 /* 16 This example shows how to operate a second button, in addition to the default DPA button connected to RB4. 17 The second button can be connected to any GPIO. In this example, RA0 was chosen. 18 Both the RB4 and the RA0 are digital inputs with weak pull-up activated. This is the default setting for RB4. 19 The buttons can operate in three different modes. See the MODE_DPA_... symbols below. 20 The MODE symbol controls the conditional compilation of the custom DPA handler for the selected mode. 21 The following simple circuit is needed for the buttons to work in any of the three modes. 22 23 RB4 RA0 24 # # 25 | | 26 | Diode | 27 | | 28 o---->|-----o 29 | | 30 | | 31 Default | o | o Second 32 DPA Button |=|> |=|> Button 33 | o | o 34 | | 35 | | 36 === === 37 GND GND 38 */ 39 40 // Both buttons open the same default DPA Menu 41 #define MODE_DPA_MENUS 0 42 // Both buttons open the DPA Menu, but they differ. DPA Menu opened by the default RB4 button does not contain menu items including StandBy and after. 43 #define MODE_DPA_MENUS_DIFERENTIATED 1 44 // Second button does not open DPA Menu, but controls Green LED. 45 #define MODE_SEPARATED 2 46 47 // The actual mode 48 #define MODE MODE_SEPARATED 49 50 //############################################################################################ 51 52 // Default IQRF include (modify the path according to your setup) 53 #include "IQRF.h" 54 55 // Default DPA header (modify the path according to your setup) 56 #include "DPA.h" 57 // Default Custom DPA Handler header (modify the path according to your setup) 58 #include "DPAcustomHandler.h" 59 60 // Second button definition 61 #define BTN2_TRIS TRISA.0 62 #define BTN2_PORT PORTA.0 63 #define BTN2_WPU WPUA.0 64 65 //############################################################################################ 66 // https://doc.iqrf.org/DpaTechGuide/pages/custom-dpa-handler.html 67 bit CustomDpaHandler() 68 //############################################################################################ 69 { 70 // Handler presence mark 71 clrwdt(); 72 73 // Detect DPA event to handle (unused event handlers can be commented out or even deleted) 74 switch ( GetDpaEvent() ) 75 { 76 // ------------------------------------------------- 77 case DpaEvent_Interrupt: 78 // Do an extra quick background interrupt work 79 // ! The time spent handling this event is critical.If there is no interrupt to handle return immediately otherwise keep the code as fast as possible. 80 // ! Make sure the event is the 1st case in the main switch statement at the handler routine.This ensures that the event is handled as the 1st one. 81 // ! It is desirable that this event is handled with immediate return even if it is not used by the custom handler because the Interrupt event is raised on every MCU interrupt and the “empty” return handler ensures the shortest possible interrupt routine response time. 82 // ! Only global variables or local ones marked by static keyword can be used to allow reentrancy. 83 // ! Make sure race condition does not occur when accessing those variables at other places. 84 // ! Make sure( inspect.lst file generated by C compiler ) compiler does not create any hidden temporary local variable( occurs when using division, multiplication or bit shifts ) at the event handler code.The name of such variable is usually Cnumbercnt. 85 // ! Do not call any OS functions except setINDFx(). 86 // ! Do not use any OS variables especially for writing access. 87 // ! All above rules apply also to any other function being called from the event handler code, although calling any function from Interrupt event is not recommended because of additional MCU stack usage. 88 // https://doc.iqrf.org/DpaTechGuide/pages/EventInterrupt.html 89 return Carry; 90 91 92 // ------------------------------------------------- 93 case DpaEvent_Idle: 94 // Do a quick background work when RF packet is not received 95 // https://doc.iqrf.org/DpaTechGuide/pages/idle.html 96 97 #if MODE == MODE_SEPARATED 98 _LEDG = !BTN2_PORT; 99 #endif 100 break; 101 102 // ------------------------------------------------- 103 case DpaEvent_MenuActivated: 104 // Called to customize DPA menu 105 // https://doc.iqrf.org/DpaTechGuide/pages/menuactivated.html 106 107 #if MODE == MODE_SEPARATED 108 109 // 2nd button pressed? 110 if ( !BTN2_PORT ) 111 _DpaMessage.PerNodeGetDpaMenuInfo_Response.FlagsExt = DMENU_Ext_DoNotOpen; 112 113 #elif MODE == MODE_DPA_MENUS_DIFERENTIATED 114 115 // 2nd button pressed? 116 if ( !BTN2_PORT ) 117 // Open default DPA Menu 118 break; 119 120 // Standard DPA button pressed => modify DPA Menu content 121 userReg1 = DMENU_Item_Unimplemented_Standby | DMENU_Item_Unimplemented_UnbondAndRestart | DMENU_Item_Unimplemented_UnbondFactorySettingsAndRestart; 122 _DpaMessage.PerNodeGetDpaMenuInfo_Response.FlagsExt = DMENU_Ext_Item_Unimplemented_Reset; 123 return TRUE; 124 125 #else // MODE == MODE_DPA_MENUS 126 // Both buttons open the same default DPA Menu 127 #endif 128 break; 129 130 // ------------------------------------------------- 131 case DpaEvent_Reset: 132 // Called after module is reset 133 // https://doc.iqrf.org/DpaTechGuide/pages/ResetEvent.html 134 { 135 static bit wasReset; 136 // Setup GPIO for the 2nd button? 137 if ( !wasReset ) 138 { 139 wasReset = TRUE; 140 // Pull-up to 2nd button 141 BTN2_WPU = 1; 142 // 2nd button is at input 143 BTN2_TRIS = 1; 144 } 145 break; 146 } 147 148 // ------------------------------------------------- 149 case DpaEvent_DpaRequest: 150 // Called to interpret DPA request for peripherals 151 // https://doc.iqrf.org/DpaTechGuide/pages/EventDpaRequest.html 152 if ( IsDpaEnumPeripheralsRequest() ) 153 { 154 // ------------------------------------------------- 155 // Peripheral enumeration 156 // https://doc.iqrf.org/DpaTechGuide/pages/enumerate-peripherals.html 157 158 _DpaMessage.EnumPeripheralsAnswer.HWPID |= 0xBB0F; 159 _DpaMessage.EnumPeripheralsAnswer.HWPIDver |= 0; 160 return TRUE; 161 } 162 163 break; 164 } 165 166 return FALSE; 167 } 168 169 //############################################################################################ 170 // Default Custom DPA Handler header; 2nd include implementing a Code bumper to detect too long code of the Custom DPA Handler (modify the path according to your setup) 171 #include "DPAcustomHandler.h" 172 //############################################################################################