1 // ********************************************************************************** 2 // Custom DPA Handler code example - Nodes polling * 3 // ********************************************************************************** 4 // Copyright (c) MICRORISC s.r.o. 5 // 6 // File: $RCSfile: CustomDpaHandler-Coordinator-PollNodes.c,v $ 7 // Version: $Revision: 1.21 $ 8 // Date: $Date: 2021/04/26 15:13:50 $ 9 // 10 // Revision history: 11 // 2017/03/13 Release for DPA 3.00 12 // 2015/08/05 Release for DPA 2.20 13 // 2014/10/31 Release for DPA 2.10 14 // 15 // ********************************************************************************** 16 17 // Online DPA documentation https://doc.iqrf.org/DpaTechGuide/ 18 19 // Default IQRF include (modify the path according to your setup) 20 #include "IQRF.h" 21 22 // Implement Custom DPA Handler for Coordinator 23 #define COORDINATOR_CUSTOM_HANDLER 24 25 // Default DPA header (modify the path according to your setup) 26 #include "DPA.h" 27 // Default Custom DPA Handler header (modify the path according to your setup) 28 #include "DPAcustomHandler.h" 29 30 // Application periodically sends a request to every node and then it reports a received response to its interface master 31 // If PeripehralRam[0].0 is set to 1, polling is disabled 32 33 // Machine states 34 typedef enum 35 { 36 // Send request to the node 37 state_SendRequest, 38 // Wait for the response from node 39 state_WaitResponse, 40 } TState; 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 // Currently polled node 51 static uns8 nodeAddr; 52 // Machine state 53 static uns8 state; 54 55 // Detect DPA event to handle 56 switch ( GetDpaEvent() ) 57 { 58 // ------------------------------------------------- 59 case DpaEvent_Init: 60 // Do a one time initialization before main loop starts 61 62 // Next node address will be 1 63 nodeAddr = MAX_ADDRESS; 64 // Next state is to send request to the next nodeAddr 65 state = state_SendRequest; 66 67 // Give GSM GW time to start SPI master 68 waitDelay( 100 ); 69 70 break; 71 72 // ------------------------------------------------- 73 case DpaEvent_Idle: 74 // Do a quick background work when RF packet is not received 75 76 // What state is the application at? 77 switch ( state ) 78 { 79 // Send request to the node 80 case state_SendRequest: 81 // If bit 0 of PeripheralRam[0] is set, nodes are not polled 82 if ( !PeripheralRam[0].0 ) 83 { 84 // Store previous node address 85 uns8 oldAddr = nodeAddr; 86 for ( ;; ) 87 { 88 // Generate next address, handle overflow 89 if ( ++nodeAddr == ( MAX_ADDRESS + 1 ) ) 90 nodeAddr = 1; 91 92 // Is the node address bonded to the network? 93 if ( isBondedNode( nodeAddr ) ) 94 { 95 // Next state is to wait for the response 96 state = state_WaitResponse; 97 98 // Send request to the node 99 _NADR = nodeAddr; 100 _NADRhigh = 0; 101 // Use OS peripheral 102 _PNUM = PNUM_OS; 103 // Read OS 104 _PCMD = CMD_OS_READ; 105 // Any HWPID 106 _HWPID = HWPID_DoNotCheck; 107 // This DPA request has no data 108 _DpaDataLength = 0; 109 // Send the DPA request 110 uns16 hopsBack = DpaApiRfTxDpaPacketCoordinator(); 111 112 // Indicate DPA Request 113 pulseLEDG(); 114 115 // Disable interrupts to prevent background change of DpaTicks variable 116 GIE = FALSE; 117 // Compute total number of hops C>N + N>C + 2 118 DpaTicks = (uns16)RTHOPS + hopsBack + 2; 119 // Response returns 11 bytes, so it will have the same slot length as request 120 DpaTicks *= RTTSLOT; 121 // Add extra 0.5s to the timeout 122 DpaTicks += 500 / 10; 123 // Enable interrupts again 124 GIE = TRUE; 125 // Exit the loop 126 break; 127 } 128 129 // If the loop is back, then there is no bonded node 130 if ( nodeAddr == oldAddr ) 131 { 132 // Wait for a response that will not happen 133 state = state_WaitResponse; 134 // and after approx. 10s try to find bonded node again 135 GIE = FALSE; 136 DpaTicks = 1024; 137 GIE = TRUE; 138 // Exit the loop 139 break; 140 } 141 } 142 } 143 break; 144 145 case state_WaitResponse: 146 // Timeout occurred? 147 if ( DpaTicks.15 != 0 ) 148 // Yes, request the next node 149 state = state_SendRequest; 150 break; 151 } 152 break; 153 154 // ------------------------------------------------- 155 case DpaEvent_ReceiveDpaResponse: 156 // Called after DPA response was received at coordinator 157 158 // Is it a response from the requested node sent by me? 159 if ( _NADR == nodeAddr && _PNUM == PNUM_OS && _PCMD == ( CMD_OS_READ | RESPONSE_FLAG ) && NetDepth == 1 ) 160 { 161 // Response received indication 162 pulseLEDR(); 163 // Yes, forward the result to the interface master, DPA value is 0 164 DpaApiSendToIFaceMaster( 0, 0 ); 165 state = state_SendRequest; 166 // Request was handled. 167 return TRUE; 168 } 169 break; 170 171 // ------------------------------------------------- 172 case DpaEvent_DpaRequest: 173 // Called to interpret DPA request for peripherals 174 // ------------------------------------------------- 175 // Peripheral enumeration 176 if ( IsDpaEnumPeripheralsRequest() ) 177 { 178 _DpaMessage.EnumPeripheralsAnswer.HWPID = 0x000F; 179 _DpaMessage.EnumPeripheralsAnswer.HWPIDver = 0xABCD; 180 return TRUE; 181 } 182 183 break; 184 } 185 186 return FALSE; 187 } 188 189 //############################################################################################ 190 // 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) 191 #include "DPAcustomHandler.h" 192 //############################################################################################