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