1 // ********************************************************************* 2 // Custom DPA Handler code example - Local FRC * 3 // ********************************************************************* 4 // Copyright (c) MICRORISC s.r.o. 5 // 6 // File: $RCSfile: CustomDpaHandler-LocalFRC.c,v $ 7 // Version: $Revision: 1.9 $ 8 // Date: $Date: 2021/04/26 15:13:50 $ 9 // 10 // Revision history: 11 // 2020/09/03 Release for DPA 4.15 12 // 13 // ********************************************************************* 14 15 // Online DPA documentation https://doc.iqrf.org/DpaTechGuide/ 16 17 // Default IQRF include (modify the path according to your setup) 18 #include "IQRF.h" 19 20 // Default DPA header (modify the path according to your setup) 21 #include "DPA.h" 22 // Default Custom DPA Handler header (modify the path according to your setup) 23 #include "DPAcustomHandler.h" 24 25 //############################################################################################ 26 27 // This minimalistic example implements both Local FRC Controller and Actuator. 28 29 // When a IQRF button is pressed, the controller sends Local FRC command to switch on/off LEDR at [Ns]1-5 (actuators). LEDG at the Controller indicates on/off status. 30 // Actuators i.e. [Ns] which received Local FRC command from the Controller must have Local FRC enabled in their configuration. 31 // Actuators use DpaEvent_VerifyLocalFrc to allow only FRC_AcknowledgedBroadcastBits and FRC_MemoryRead[Plus1] FRCs with embedded DPA Request with PNUM_LEDR. Also only Local FRC Controllers with odd address are allowed to control the Actuator. 32 33 34 // Choose local FRC command to be used: 35 36 // This (1 byte) FRC command executes embedded DPA Request immediately. DPA Request must be processed within 40 ms and maximum 63 [Ns] can be addressed. 37 //#define LOCAL_FRC_CMD FRC_MemoryReadPlus1 38 // This (2 bit) FRC command executes embedded DPA Request after the whole FRC process is finished (delay might be noticed). Maximum 239 [Ns] can be addressed. DPA Request execution time is not limited. 39 #define LOCAL_FRC_CMD FRC_AcknowledgedBroadcastBits 40 41 42 // Must be the 1st defined function in the source code in order to be placed at the correct FLASH location! 43 //############################################################################################ 44 bit CustomDpaHandler() 45 //############################################################################################ 46 { 47 // Handler presence mark 48 clrwdt(); 49 50 // Detect DPA event to handle (unused event handlers can be commented out or even deleted) 51 switch ( GetDpaEvent() ) 52 { 53 // ------------------------------------------------- 54 case DpaEvent_Interrupt: 55 // Do an extra quick background interrupt work 56 return Carry; 57 58 // ------------------------------------------------- 59 case DpaEvent_Idle: 60 // Do a quick background work when RF packet is not received 61 62 { // ###### Local FRC Controller part ###### 63 static bit wasButtonPressed; 64 65 // If the button is pressed, send appropriate Local FRC command to switch on/off the actuator 66 if ( buttonPressed ) 67 { 68 if ( !wasButtonPressed ) 69 { 70 // Selected [Ns] bitmap for Local FRC. In this example it is hard-coded. In real application it might be read from EEPROM. 71 clearBufferINFO(); 72 // [Ns] 1-5 73 bufferINFO[0] = 0b111110; 74 75 // Prepare DPA Request. In this example it is hard-coded. In real application it might be read from EEPROM. 76 // W = PCMD 77 static bit offOrOn; 78 offOrOn = !offOrOn; 79 if ( offOrOn ) 80 { 81 setLEDG(); 82 W = CMD_LED_SET_ON; 83 } 84 else 85 { 86 stopLEDG(); 87 W = CMD_LED_SET_OFF; 88 } 89 90 // FRC User data structure varies according the actual FRC command used 91 #if LOCAL_FRC_CMD == FRC_AcknowledgedBroadcastBits 92 // PCMD 93 DataInSendFRC[2] = W; 94 // Total DPA Request length 95 DataInSendFRC[0] = 5; 96 // PNUM 97 DataInSendFRC[1] = PNUM_LEDR; 98 // HWPID 99 DataInSendFRC[3] = HWPID_DoNotCheck & 0xFF; 100 DataInSendFRC[4] = HWPID_DoNotCheck >> 8; 101 #elif LOCAL_FRC_CMD == FRC_MemoryReadPlus1 || LOCAL_FRC_CMD == FRC_MemoryRead 102 // PCMD 103 DataInSendFRC[3] = W; 104 // Memory address 105 DataInSendFRC[0] = ( (uns16)&_DpaMessage.Response.PData[0] ) & 0xFF; 106 DataInSendFRC[1] = ( (uns16)&_DpaMessage.Response.PData[0] ) >> 8; 107 // PNUM 108 DataInSendFRC[2] = PNUM_LEDR; 109 // DPA Request data length 110 DataInSendFRC[4] = 0; 111 #else 112 #error Unimplemented FRC Command 113 #endif 114 115 // Do local FRC 116 // If some addressed Nodes except me did not answer, keep LEDG pulsing to indicate it 117 if ( DpaApiLocalFrc( LOCAL_FRC_CMD, RFpower ) + 1 != param2 ) 118 pulsingLEDG(); 119 // Note: workaround to resolve the missing internal reset of the _localFRC variable at IQRF OS 4.04D 120 _localFRC = FALSE; 121 } 122 123 wasButtonPressed = TRUE; 124 } 125 else 126 wasButtonPressed = FALSE; 127 128 break; 129 } 130 131 // ------------------------------------------------- 132 case DpaEvent_VerifyLocalFrc: 133 // Called to verify local FRC command 134 135 // ###### Local FRC Actuator part ###### 136 // Allow only certain FRC commands, DPA Requests and Local FRC Controller addresses 137 138 // Ignore Local FRC send from even [Ns] Controllers 139 if ( !TX.0 ) 140 break; 141 142 // Allow only certain FRC commands and DPA Request peripherals (LEDR) to work with 143 switch ( _PCMD ) 144 { 145 case FRC_AcknowledgedBroadcastBits: 146 if ( DataOutBeforeResponseFRC[1] == PNUM_LEDR ) 147 goto DpaHandleReturnTRUE; 148 break; 149 150 case FRC_MemoryRead: 151 case FRC_MemoryReadPlus1: 152 if ( DataOutBeforeResponseFRC[2] == PNUM_LEDR ) 153 goto DpaHandleReturnTRUE; 154 break; 155 } 156 157 break; 158 159 // ------------------------------------------------- 160 case DpaEvent_DpaRequest: 161 // Called to interpret DPA request for peripherals 162 if ( IsDpaEnumPeripheralsRequest() ) 163 { 164 // ------------------------------------------------- 165 // Peripheral enumeration 166 _DpaMessage.EnumPeripheralsAnswer.HWPID = 0xF5CF; 167 168 DpaHandleReturnTRUE: 169 return TRUE; 170 } 171 172 break; 173 } 174 175 DpaHandleReturnFALSE: 176 return FALSE; 177 } 178 179 //############################################################################################ 180 // Default Custom DPA Handler header; 2nd include to implement Code bumper to detect too long code of the Custom DPA Handler (modify the path according to your setup) 181 #include "DPAcustomHandler.h" 182 //############################################################################################