FreeHIL
Loading...
Searching...
No Matches
FH_RFCommunication.c
Go to the documentation of this file.
1/**
2 * @file
3 * @brief
4 * <b>File Map:</b>\n
5 * <b>FH_Setup</b>, Section <b>FH_RFCommunication</b>\n
6 * This file is the main source of the communication between <b>RobotFramework</b> and the micro-controller on which <b>FH</b> source code is ported\n
7 * The micro-controller on which <b>FH</b> source code is ported, could be simply utilized in a <b>RS485 network</b>\n
8 * In other word, multiple devices or multiple cards could be simply utilized where every device or every card has its own address\n
9 * Address of the device (or card) for every device (or card) is set by <b>FH</b> user in <b>FH_DeviceAddress.h</b>\n
10 * An interested UART (called <b>Communication Dedicated UART</b>) by the <b>FH</b> user for the communication between <b>RobotFramework</b> and the micro-controller on which <b>FH</b> source code is ported, shall be dedicated\n
11 *
12 * @note To have a clean code, <b>FH</b> user should have the implementation of the initialization and send functions of the <b>Communication Dedicated UART</b> in a separate c file\n
13 * Then <b>FH</b> user should include the header file <b>(.h)</b> of the related source file <b>(.c)</b> here\n
14 * This header file shall include the following items:\n
15 * The declaration of the initialization function of the <b>Communication Dedicated UART</b>\n
16 * The declaration of the send function of the <b>Communication Dedicated UART</b>
17 *
18 * @note <b>FH</b> user shall use <b>FH_RFCommunication_ReceiveBuf</b> and <b>FH_RFCommunication_ReceiveBufIndex</b> in the receive <b>ISR</b> (Interrupt Service Routine) of the <b>Communication Dedicated UART</b> in a separate c file\n
19 * For this to happen, <b>FH</b> user shall just include <b>FH_RFCommunication_GlobalVariables.h</b> there\n
20 * In other word, <b>FH_RFCommunication_ReceiveBuf</b> array shall receive every byte of the received data there with <b>FH_RFCommunication_ReceiveBufIndex</b> as index of the array
21 *
22 * @attention
23 * <b>FH_RFCommunication_Message</b> is the structure for receiving the message frame from <b>RobotFramework</b>\n
24 * The first data in this structure is the <b>DeviceAddress</b>\n
25 * If a message (from <b>RobotFramework</b>) with a different <b>DeviceAddress</b> than the one set in <b>FH_DeviceAddress.h</b> is received, it will be ignored and not processed
26 * @note
27 * If there is just one device (or card), there is no need for the <b>FH</b> user to change the default address which is already <b>0x01</b>\n
28 * In this case, the address of the message in the message frame (in <b>RobotFramework</b>) shall be set to <b>01</b>
29 *
30 * @verbatim
31 ==============================================================================
32 ##### RobotFramework Example #####
33 ==============================================================================
34 @{MessageData} = Create List ${DO01} ${DO_Set}
35 &{Message} = Create Dictionary DeviceAddress=${DeviceAddress_01} Function=${Function_DO} Command=${DO_Commands_SetStatus} Data=@{MessageData}
36 ${Result} SendMessage &{Message}
37
38 Comments:
39
40 DO01 => It indicates the Digital Output 01
41 DO_Set => It indicates the Digital Output 01 shall be Set (DO_Reset indicates the Digital Output 01 shall be Reset)
42 DeviceAddress_01 => It shall be equal to the address of the device: FH_RFCommunication_DeviceAddress
43 Function_DO => It is the function in the message frame
44 DO_Commands_SetStatus => It is the command of the function in the message frame
45 @endverbatim
46 *
47 * @note If at least one byte of data is received through the <b>ISR</b> (Interrupt Service Routine) of the <b>Communication Dedicated UART</b> by the <b>FH</b> user, a complete message shall be received in a maximum defined timeout\n
48 * The received data in the <b>ISR</b> (Interrupt Service Routine) will be ignored if the complete message will not be received within the defined timeout\n
49 * For this to happen, <b>FH_GlobalTimeCounter</b> is utilized to calculate the maximum timeout\n
50 * <b>FH_RFCommunication_ReceiveBufMaxTimeout</b> is the defined maximum timeout for every byte\n
51 * In the <b>ISR</b> (Interrupt Service Routine) of the <b>Communication Dedicated UART</b> by the <b>FH</b> user, <b>FH_GlobalTimeCounter</b> shall be reset after receiving every byte of data
52 *
53 * @note If at least one byte of data is received through the <b>ISR</b> (Interrupt Service Routine) of the <b>Communication Dedicated UART</b> by the <b>FH</b> user, a complete message shall be received in a maximum defined timeout\n
54 * The received data in the <b>ISR</b> (Interrupt Service Routine) will be ignored if the complete message will not be received within the defined timeout\n
55 * For this to happen, <b>FH_GlobalTimeCounter</b> is utilized to calculate the maximum timeout\n
56 * <b>FH_RFCommunication_ReceiveBufMaxTimeout</b> is the defined maximum timeout for every byte\n
57 * In the <b>ISR</b> (Interrupt Service Routine) of the <b>Communication Dedicated UART</b> by the <b>FH</b> user, <b>FH_GlobalTimeCounter</b> shall be reset after receiving every byte of data
58 *
59 * @warning If <b>FH</b> user would not increment the <b>FH_GlobalTimeCounter</b> in a timer <b>ISR</b> (Interrupt Service Routine) every 1 mili-second, there will be a malfunction here
60 *
61 * @attention There are a total number of <b>3 attentions</b> (<b>FH</b> user defined code) in this file where <b>FH</b> user shall insert some code\n
62 * Other parts could be left intact
63 *
64 *******************************************************************************
65 * SPDX-License-Identifier: Apache-2.0
66 *
67 * Copyright 2026 Vahid Hasirchi
68 *
69 * Licensed under the Apache License, Version 2.0 (the "License");
70 * you may not use this file except in compliance with the License.
71 * You may obtain a copy of the License at
72 *
73 * http://www.apache.org/licenses/LICENSE-2.0
74 *
75 * Unless required by applicable law or agreed to in writing, software
76 * distributed under the License is distributed on an "AS IS" BASIS,
77 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78 * See the License for the specific language governing permissions and
79 * limitations under the License.
80 ********************************************************************************
81
82 *
83 * <b>For more information refer to FreeHIL.com</b>
84 *
85*/
86/* Includes ------------------------------------------------------------------*/
88// Attention 1: FH user defined code (include the mentioned header file here)
89
90//
92
105
106/*!
107 <b>FH</b> user shall use <b>FH_RFCommunication_ReceiveBuf</b> in the receive <b>ISR</b> (Interrupt Service Routine) of the <b>Communication Dedicated UART</b> in a separate c file\n
108 For this to happen, FH user shall just include <b>FH_RFCommunication_GlobalVariables.h</b> there\n
109 In other word, <b>FH_RFCommunication_ReceiveBuf</b> array shall receive every byte of the received data there\n
110 It is configurable in <b>FH_RFCommunication_Configs.h</b>
111*/
113
114/*!
115 <b>FH_RFCommunication_ReceiveBufIndex</b> is the index of <b>FH_RFCommunication_ReceiveBuf</b>
116*/
118
119/*!
120 <b>FH_RFCommunication_SendBuf</b> is the data buffer for sending back the response to the received message through the <b>Communication Dedicated UART</b>\n
121 In other word, it is the data buffer to send the response back to the <b>RobotFramework</b>
122 It is configurable in <b>FH_RFCommunication_Configs.h</b>
123*/
125
126/*!
127 <b>FH_RFCommunication_ReceiveBufReadIndex</b> is the index of the data which is read from the <b>FH_RFCommunication_ReceiveBuf</b> to be processed\n
128 It is used in <b>FH_RFCommunication_Receive</b> function to help process the received data through the <b>Communication Dedicated UART</b>
129*/
131
132/*!
133 <b>FH_RFCommunication_Message_DataIndex</b> is the index of the data part of the message frame\n
134 It is used in <b>FH_RFCommunication_Receive</b> function to help collect the received data part of the message frame through the <b>Communication Dedicated UART</b>
135 For more information, refer to <b>FH_RFCommunication_Message</b>
136*/
138
139/*!
140 <b>FH_RFCommunication_Message</b> is the structure for receiving the message frame from <b>RobotFramework</b>\n
141*/
143
144/*!
145 <b>FH_RFCommunication_State</b> is the enumeration utilized as state machine to collect the different blocks of the message frame from <b>RobotFramework</b>\n
146 It is initialized with <b>RFCommunication_STATE_IDLE</b> to be ready to collect a new message from <b>RobotFramework</b>
147*/
149
150/**
151 * @brief This function initializes the <b>Communication Dedicated UART</b>\n
152 * The <b>Communication Dedicated UART</b> could be any interested UART of the micro-controller on which <b>FH</b> source code is ported\n
153 * <b>FH</b> user should call the initialization function of the interested UART here
154 *
155 * @param None
156 *
157 * @return FH_ErrorInfo is returned
158 *
159 * @note
160 * To have a clean code, just include the related header file\n
161 * Then just call the function here
162 *
163 * @warning
164 * To be able to send or receive data through the <b>Communication Dedicated UART</b> of the micro-controller on which <b>FH</b> source code is ported, this function shall be invoked once in the <b>main.c</b> file firstly\n
165 *
166
167*/
169{
170 FH_ErrorInfo fh_ErrorInfo; // Error Information
171 FH_ResetErrorInfo(&fh_ErrorInfo); // Reset Error Information to default
172
173 FH_RFCommunication_ReceiveBufIndex = 0; // Reset FH_RFCommunication_ReceiveBufIndex
174
175 // Attention 2: FH user defined code (call the initialization function of the Communication Dedicated UART here)
176
177 // YourInitializationFunctionName ();
178
179 //
180
181 return fh_ErrorInfo;
182}
183
184/**
185 * @brief This function sends data through the <b>Communication Dedicated UART</b>\n
186 * The <b>Communication Dedicated UART</b> could be any interested UART of the micro-controller on which <b>FH</b> source code is ported\n
187 * <b>FH</b> user should call the send function of the interested UART here
188 *
189 * @param DataString
190 * a null terminated string of data to be sent
191 *
192 * @return FH_ErrorInfo is returned
193 *
194 * @note
195 * To have a clean code, just include the related header file\n
196 * Then just call the function here
197 *
198 * @warning
199 * To be able to send data through the <b>Communication Dedicated UART</b> of the micro-controller on which <b>FH</b> source code is ported, the <b>FH_RFCommunication_Init</b> function shall be invoked once in the <b>main.c</b> file firstly\n
200 *
201
202*/
204{
205 FH_ErrorInfo fh_ErrorInfo; // Error Information
206 FH_ResetErrorInfo(&fh_ErrorInfo); // Reset Error Information to default
207
208 // Attention 3: FH user defined code (call the send process function of the Communication Dedicated UART here with DataString as argument)
209 // Hint: The prototype of the send process function should be something like YourSendProcessFunctionName(uint8_t* Data);
210
211 // YourSendProcessFunctionName (DataString);
212
213 //
214
215 return fh_ErrorInfo;
216}
217
218/**
219 * @brief
220 * This function is the main source of receiving a complete message from <b>RobotFramework</b>\n
221 * The micro-controller on which <b>FH</b> source code is ported, could be simply utilized in a <b>RS485 network</b>\n
222 * In other word, multiple devices or multiple cards could be simply utilized where every device or every card has its own address\n
223 * Address of the device (or card) for every device (or card) is set by <b>FH</b> user in <b>FH_DeviceAddress.h</b>\n
224 * An interested UART (called <b>Communication Dedicated UART</b>) by the <b>FH</b> user for the communication between <b>RobotFramework</b> and the micro-controller on which <b>FH</b> source code is ported, shall be dedicated\n
225 *
226 * @param None
227 *
228 * @return FH_ErrorInfo is returned
229 *
230 * @note <b>FH</b> user shall use <b>FH_RFCommunication_ReceiveBuf</b> and <b>FH_RFCommunication_ReceiveBufIndex</b> in the receive <b>ISR</b> (Interrupt Service Routine) of the <b>Communication Dedicated UART</b> in a separate c file\n
231 * For this to happen, <b>FH</b> user shall just include <b>FH_RFCommunication_GlobalVariables.h</b> there\n
232 * In other word, <b>FH_RFCommunication_ReceiveBuf</b> array shall receive every byte of the received data there with <b>FH_RFCommunication_ReceiveBufIndex</b> as index of the array
233 *
234 * @attention
235 * <b>FH_RFCommunication_Message</b> is the structure for receiving the message frame from <b>RobotFramework</b>\n
236 * The first data in this structure is the <b>DeviceAddress</b>\n
237 * If a message (from <b>RobotFramework</b>) with a different <b>DeviceAddress</b> than the one set in <b>FH_DeviceAddress.h</b> is received, it will be ignored and not processed
238 *
239 * @note
240 * If there is just one device (or card), there is no need for the <b>FH</b> user to change the default address which is already <b>0x01</b>\n
241 * In this case, the address of the message in the message frame (in <b>RobotFramework</b>) shall be set to <b>01</b>
242 *
243 * @verbatim
244 ==============================================================================
245 ##### RobotFramework Example #####
246 ==============================================================================
247 @{MessageData} = Create List ${DO01} ${DO_Set}
248 &{Message} = Create Dictionary DeviceAddress=${DeviceAddress_01} Function=${Function_DO} Command=${DO_Commands_SetStatus} Data=@{MessageData}
249 ${Result} SendMessage &{Message}
250
251 Comments:
252
253 DO01 => It indicates the Digital Output 01
254 DO_Set => It indicates the Digital Output 01 shall be Set (DO_Reset indicates the Digital Output 01 shall be Reset)
255 DeviceAddress_01 => It shall be equal to the address of the device: FH_RFCommunication_DeviceAddress
256 Function_DO => It is the function in the message frame
257 DO_Commands_SetStatus => It is the command of the function in the message frame
258 @endverbatim
259 *
260 * @note If at least one byte of data is received through the <b>ISR</b> (Interrupt Service Routine) of the <b>Communication Dedicated UART</b> by the <b>FH</b> user, a complete message shall be received in a maximum defined timeout\n
261 * The received data in the <b>ISR</b> (Interrupt Service Routine) will be ignored if the complete message will not be received within the defined timeout\n
262 * For this to happen, <b>FH_GlobalTimeCounter</b> is utilized to calculate the maximum timeout\n
263 * <b>FH_RFCommunication_ReceiveBufMaxTimeout</b> is the defined maximum timeout for every byte\n
264 * In the <b>ISR</b> (Interrupt Service Routine) of the <b>Communication Dedicated UART</b> by the <b>FH</b> user, <b>FH_GlobalTimeCounter</b> shall be reset after receiving every byte of data
265 *
266 * @note If at least one byte of data is received through the <b>ISR</b> (Interrupt Service Routine) of the <b>Communication Dedicated UART</b> by the <b>FH</b> user, a complete message shall be received in a maximum defined timeout\n
267 * The received data in the <b>ISR</b> (Interrupt Service Routine) will be ignored if the complete message will not be received within the defined timeout\n
268 * For this to happen, <b>FH_GlobalTimeCounter</b> is utilized to calculate the maximum timeout\n
269 * <b>FH_RFCommunication_ReceiveBufMaxTimeout</b> is the defined maximum timeout for every byte\n
270 * In the <b>ISR</b> (Interrupt Service Routine) of the <b>Communication Dedicated UART</b> by the <b>FH</b> user, <b>FH_GlobalTimeCounter</b> shall be reset after receiving every byte of data
271 *
272 * @warning If <b>FH</b> user would not increment the <b>FH_GlobalTimeCounter</b> in a timer <b>ISR</b> (Interrupt Service Routine) every 1 mili-second, there will be a malfunction here
273 *
274 * @attention <b>FH</b> user could left this function intact
275 *
276 * @note
277 * <b>FH_RFCommunication_Message</b> is the structure for receiving the message frame from <b>RobotFramework</b>\n
278 * <b>FH_RFCommunication_State</b> is the enumeration utilized as state machine to collect the different blocks of the message frame from <b>RobotFramework</b>\n
279 * It is initialized with <b>RFCommunication_STATE_IDLE</b> to be ready to collect a new message from <b>RobotFramework</b>
280 *
281 * @note
282 * <b>FH_RFCommunication_ReceiveBufReadIndex</b> is the index of the data which is read from the <b>FH_RFCommunication_ReceiveBuf</b> to be processed\n
283 * It is used to help process the received data through the <b>Communication Dedicated UART</b>
284 *
285 * @note
286 * <b>FH_RFCommunication_Message_DataIndex</b> is the index of the data part of the message frame\n
287 * It is used in <b>FH_RFCommunication_Receive</b> function to help collect the received data part of the message frame through the <b>Communication Dedicated UART</b>
288 * For more information, refer to <b>FH_RFCommunication_Message</b>
289 *
290 *******************************************************************************
291 * SPDX-License-Identifier: Apache-2.0
292 *
293 * Copyright 2026 Vahid Hasirchi
294 *
295 * Licensed under the Apache License, Version 2.0 (the "License");
296 * you may not use this file except in compliance with the License.
297 * You may obtain a copy of the License at
298 *
299 * http://www.apache.org/licenses/LICENSE-2.0
300 *
301 * Unless required by applicable law or agreed to in writing, software
302 * distributed under the License is distributed on an "AS IS" BASIS,
303 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
304 * See the License for the specific language governing permissions and
305 * limitations under the License.
306 ********************************************************************************
307
308 *
309 * <b>For more information refer to FreeHIL.com</b>
310 *
311*/
313{
314 FH_ErrorInfo fh_ErrorInfo; // Error Information
315 FH_ResetErrorInfo(&fh_ErrorInfo); // Reset Error Information to default
316
317 if (FH_RFCommunication_ReceiveBufIndex > 0) // If there is at least one byte of data available in the ISR (Interrupt Service Routine)
318 {
319 FH_RFCommunication_ReceiveBufReadIndex = 0; // The index of the data which is read from the FH_RFCommunication_ReceiveBuf
320 fh_RFCommunication_State = RFCommunication_STATE_DeviceAddress; // The state to verify the device (or card) address
321 FH_RFCommunication_Message_DataIndex = 0; // The index of the data part of the message frame
322
323 while (fh_RFCommunication_State != RFCommunication_STATE_MessageReceived && // Loop till receiving a complete message
324 FH_GlobalTimeCounter < FH_RFCommunication_ReceiveBufMaxTimeout) // Loop timeout till receiving a complete message (Exit the loop if the timer counter exceeds the FH_RFCommunication_ReceiveBufMaxTimeout)
325 {
326 if (FH_RFCommunication_ReceiveBufReadIndex < FH_RFCommunication_ReceiveBufIndex) // If there is yet at least one byte of data in FH_RFCommunication_ReceiveBuf which is not yet read
327 {
328 switch (fh_RFCommunication_State) // Check different states
329 {
330 case RFCommunication_STATE_DeviceAddress: // The state to receive the device (or card) address of the message
331 if (FH_RFCommunication_ReceiveBufReadIndex == RFCommunication_DeviceAddress) // If the read index is on the device address part of the message
332 {
333 if (FH_RFCommunication_ReceiveBuf[RFCommunication_DeviceAddress] == FH_RFCommunication_DeviceAddress) // If the device (or card) address in the message is true
334 {
335 fh_RFCommunication_Message -> DeviceAddress = FH_RFCommunication_ReceiveBuf[RFCommunication_DeviceAddress]; // Set the device (or card) address part of the message
336 fh_RFCommunication_State = RFCommunication_STATE_Function; // Go to the next state which is the function part of the message
337 FH_RFCommunication_ReceiveBufReadIndex = FH_RFCommunication_ReceiveBufReadIndex + 1; // Increase the index of the data which is read from the FH_RFCommunication_ReceiveBuf
338 }
339 else // If the device (or card) address in the message is not true
340 {
341 FH_RFCommunication_ReceiveBufIndex = 0; // Reset the index of the receive buffer
342 fh_RFCommunication_State = RFCommunication_STATE_IDLE; // Go to the RFCommunication_STATE_IDLE state
343 fh_ErrorInfo.error_code = FH_ERROR_MessageFrame; // There is FH_ERROR_MessageFrame error
344 return fh_ErrorInfo;
345 }
346 }
347 break;
348 case RFCommunication_STATE_Function: // The state to receive the function part of the message
349 if (FH_RFCommunication_ReceiveBufReadIndex == RFCommunication_Function) // If the read index is on the function part of the message
350 {
351 fh_RFCommunication_Message -> Function = FH_RFCommunication_ReceiveBuf[RFCommunication_Function]; // Set the function part of the message
352 fh_RFCommunication_State = RFCommunication_STATE_Command; // Go to the next state which is the command part of the message
353 FH_RFCommunication_ReceiveBufReadIndex = FH_RFCommunication_ReceiveBufReadIndex + 1; // Increase the index of the data which is read from the FH_RFCommunication_ReceiveBuf
354 }
355 break;
356 case RFCommunication_STATE_Command: // The state to receive the command part of the message
357 if (FH_RFCommunication_ReceiveBufReadIndex == RFCommunication_Command) // If the read index is on the command part of the message
358 {
359 fh_RFCommunication_Message -> Command = FH_RFCommunication_ReceiveBuf[RFCommunication_Command]; // Set the command part of the message
360 fh_RFCommunication_State = RFCommunication_STATE_DataLength; // Go to the next state which is the data length part of the message
361 FH_RFCommunication_ReceiveBufReadIndex = FH_RFCommunication_ReceiveBufReadIndex + 1; // Increase the index of the data which is read from the FH_RFCommunication_ReceiveBuf
362 }
363 break;
364 case RFCommunication_STATE_DataLength: // The state to receive the data length part of the message
365 if (FH_RFCommunication_ReceiveBufReadIndex == RFCommunication_DataLength) // If the read index is on the data length part of the message
366 {
367 fh_RFCommunication_Message -> DataLength = FH_RFCommunication_ReceiveBuf[RFCommunication_DataLength]; // Set the data length part of the message
368 fh_RFCommunication_State = RFCommunication_STATE_Data; // Go to the next state which is the data part of the message
369 FH_RFCommunication_ReceiveBufReadIndex = FH_RFCommunication_ReceiveBufReadIndex + 1; // Increase the index of the data which is read from the FH_RFCommunication_ReceiveBuf
370 }
371 break;
372 case RFCommunication_STATE_Data: // The state to receive the data part of the message (Which may be more than one bytes of data)
373 if (FH_RFCommunication_ReceiveBufReadIndex < (fh_RFCommunication_Message -> DataLength + FH_RFCommunication_MinCommandSize - 1)) // If the read index is yet on the data part of the message
374 {
376 FH_RFCommunication_ReceiveBufReadIndex = FH_RFCommunication_ReceiveBufReadIndex + 1; // Increase the index of the data which is read from the FH_RFCommunication_ReceiveBuf
377 }
378 else
379 {
380 fh_RFCommunication_State = RFCommunication_STATE_Checksum; // Go to the next state which is the checksum part of the message
381 }
382 break;
383 case RFCommunication_STATE_Checksum: // The state to receive the checksum part of the message
384 if (FH_RFCommunication_ReceiveBufReadIndex == (fh_RFCommunication_Message -> DataLength + FH_RFCommunication_MinCommandSize - 1)) // If the read index is on the checksum part of the message
385 {
386 fh_RFCommunication_Message -> Checksum = FH_RFCommunication_ReceiveBuf[FH_RFCommunication_ReceiveBufReadIndex]; // Set the checksum part of the message
387 // For user-friendly design purposes, not implemented => always 0xAA
388 //if () // If the checksum is true
389 //{
390 fh_RFCommunication_State = RFCommunication_STATE_MessageReceived; // A complete message is received (Exit the loop)
391 //}
392 //else // If the checksum is not true
393 //{
394 // FH_RFCommunication_ReceiveBufIndex = 0; // Reset the index of the receive buffer
395 // fh_RFCommunication_State = RFCommunication_STATE_IDLE;
396 // fh_ErrorInfo.error_code = FH_ERROR_MessageFrame;
397 // return fh_ErrorInfo;
398 //}
399 }
400 break;
401 case RFCommunication_STATE_MessageReceived: // A complete message is received and the loop ends up
402 break;
403 default:
404 break;
405 }
406 }
407 }
408
409 FH_RFCommunication_ReceiveBufIndex = 0; // Reset the index of the receive buffer
410 if (fh_RFCommunication_State == RFCommunication_STATE_MessageReceived) // If a complete message is received
411 {
412 fh_RFCommunication_State = RFCommunication_STATE_IDLE; // Ready to collect a new message
413 fh_ErrorInfo.error_code = FH_ERROR_OK; // There is no error and a complete message is received
414 return fh_ErrorInfo;
415 }
416 else // A complete message is not received within the specified timeout
417 {
418 fh_RFCommunication_State = RFCommunication_STATE_IDLE; // Ready to collect a new message
419 fh_ErrorInfo.error_code = FH_ERROR_Timeout; // There is timeout error
420 return fh_ErrorInfo;
421 }
422 }
423 else // If there is not at least one byte of data available in the ISR (Interrupt Service Routine)
424 {
425 fh_ErrorInfo.error_code = FH_ERROR_NoInfo; // There is no information yet
426 return fh_ErrorInfo;
427 }
428
429}
430
431/**
432 * @brief
433 * This function verifies if a complete message from <b>RobotFramework</b> is received or not and if yes, calls the related function\n
434 * The micro-controller on which <b>FH</b> source code is ported, could be simply utilized in a <b>RS485 network</b>\n
435 * In other word, multiple devices or multiple cards could be simply utilized where every device or every card has its own address\n
436 * Address of the device (or card) for every device (or card) is set by <b>FH</b> user in <b>FH_DeviceAddress.h</b>\n
437 * An interested UART (called <b>Communication Dedicated UART</b>) by the <b>FH</b> user for the communication between <b>RobotFramework</b> and the micro-controller on which <b>FH</b> source code is ported, shall be dedicated\n
438 *
439 * @param None
440 *
441 * @return FH_ErrorInfo is returned
442 *
443 * @note <b>FH</b> user shall use <b>FH_RFCommunication_ReceiveBuf</b> and <b>FH_RFCommunication_ReceiveBufIndex</b> in the receive <b>ISR</b> (Interrupt Service Routine) of the <b>Communication Dedicated UART</b> in a separate c file\n
444 * For this to happen, <b>FH</b> user shall just include <b>FH_RFCommunication_GlobalVariables.h</b> there\n
445 * In other word, <b>FH_RFCommunication_ReceiveBuf</b> array shall receive every byte of the received data there with <b>FH_RFCommunication_ReceiveBufIndex</b> as index of the array
446 *
447 * @attention
448 * <b>FH_RFCommunication_Message</b> is the structure for receiving the message frame from <b>RobotFramework</b>\n
449 * The first data in this structure is the <b>DeviceAddress</b>\n
450 * If a message (from <b>RobotFramework</b>) with a different <b>DeviceAddress</b> than the one set in <b>FH_DeviceAddress.h</b> is received, it will be ignored and not processed
451 *
452 * @note
453 * If there is just one device (or card), there is no need for the <b>FH</b> user to change the default address which is already <b>0x01</b>\n
454 * In this case, the address of the message in the message frame (in <b>RobotFramework</b>) shall be set to <b>01</b>
455 *
456 * @verbatim
457 ==============================================================================
458 ##### RobotFramework Example #####
459 ==============================================================================
460 @{MessageData} = Create List ${DO01} ${DO_Set}
461 &{Message} = Create Dictionary DeviceAddress=${DeviceAddress_01} Function=${Function_DO} Command=${DO_Commands_SetStatus} Data=@{MessageData}
462 ${Result} SendMessage &{Message}
463
464 Comments:
465
466 DO01 => It indicates the Digital Output 01
467 DO_Set => It indicates the Digital Output 01 shall be Set (DO_Reset indicates the Digital Output 01 shall be Reset)
468 DeviceAddress_01 => It shall be equal to the address of the device: FH_RFCommunication_DeviceAddress
469 Function_DO => It is the function in the message frame
470 DO_Commands_SetStatus => It is the command of the function in the message frame
471 @endverbatim
472 *
473 * @note If at least one byte of data is received through the <b>ISR</b> (Interrupt Service Routine) of the <b>Communication Dedicated UART</b> by the <b>FH</b> user, a complete message shall be received in a maximum defined timeout\n
474 * The received data in the <b>ISR</b> (Interrupt Service Routine) will be ignored if the complete message will not be received within the defined timeout\n
475 * For this to happen, <b>FH_GlobalTimeCounter</b> is utilized to calculate the maximum timeout\n
476 * <b>FH_RFCommunication_ReceiveBufMaxTimeout</b> is the defined maximum timeout for every byte\n
477 * In the <b>ISR</b> (Interrupt Service Routine) of the <b>Communication Dedicated UART</b> by the <b>FH</b> user, <b>FH_GlobalTimeCounter</b> shall be reset after receiving every byte of data
478 *
479 * @note If at least one byte of data is received through the <b>ISR</b> (Interrupt Service Routine) of the <b>Communication Dedicated UART</b> by the <b>FH</b> user, a complete message shall be received in a maximum defined timeout\n
480 * The received data in the <b>ISR</b> (Interrupt Service Routine) will be ignored if the complete message will not be received within the defined timeout\n
481 * For this to happen, <b>FH_GlobalTimeCounter</b> is utilized to calculate the maximum timeout\n
482 * <b>FH_RFCommunication_ReceiveBufMaxTimeout</b> is the defined maximum timeout for every byte\n
483 * In the <b>ISR</b> (Interrupt Service Routine) of the <b>Communication Dedicated UART</b> by the <b>FH</b> user, <b>FH_GlobalTimeCounter</b> shall be reset after receiving every byte of data
484 *
485 * @warning If <b>FH</b> user would not increment the <b>FH_GlobalTimeCounter</b> in a timer <b>ISR</b> (Interrupt Service Routine) every 1 mili-second, there will be a malfunction here
486 *
487 * @attention <b>FH</b> user could left this function intact
488 *
489 *******************************************************************************
490 * SPDX-License-Identifier: Apache-2.0
491 *
492 * Copyright 2026 Vahid Hasirchi
493 *
494 * Licensed under the Apache License, Version 2.0 (the "License");
495 * you may not use this file except in compliance with the License.
496 * You may obtain a copy of the License at
497 *
498 * http://www.apache.org/licenses/LICENSE-2.0
499 *
500 * Unless required by applicable law or agreed to in writing, software
501 * distributed under the License is distributed on an "AS IS" BASIS,
502 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
503 * See the License for the specific language governing permissions and
504 * limitations under the License.
505 ********************************************************************************
506
507 *
508 * <b>For more information refer to FreeHIL.com</b>
509 *
510*/
512{
513 FH_ErrorInfo fh_ErrorInfo; // Error Information
514 FH_ResetErrorInfo(&fh_ErrorInfo); // Reset Error Information to default
515
516 fh_ErrorInfo = FH_RFCommunication_Receive(); // Call the main source of receiving a complete message
517
518 if (fh_ErrorInfo.error_code == FH_ERROR_OK) // If there is no error and a complete message is received
519 {
520 switch (fh_RFCommunication_Message -> Function) // Check different functions
521 {
522 case RFCommunication_Function_DO: // If DO (Digital Output) function is received
523 #if FH_DO_MaxPeripheralNumber > 0 // It is configurable in FH_DevicePeripherals.h
524 fh_ErrorInfo = FH_DO_RFCommunication (fh_RFCommunication_Message); // Process DO (Digital Output) function
525 #endif
526 break;
527 case RFCommunication_Function_DI: // If DI (Digital Input) function is received
528 #if FH_DI_MaxPeripheralNumber > 0 // It is configurable in FH_DevicePeripherals.h
529 fh_ErrorInfo = FH_DI_RFCommunication (fh_RFCommunication_Message); // Process DI (Digital Input) function
530 #endif
531 break;
532 case RFCommunication_Function_AO: // If AO (Analog Output) function is received
533 #if FH_AO_MaxPeripheralNumber > 0 // It is configurable in FH_DevicePeripherals.h
534 fh_ErrorInfo = FH_AO_RFCommunication (fh_RFCommunication_Message); // Process AO (Analog Output) function
535 #endif
536 break;
537 case RFCommunication_Function_AI: // If AI (Analog Input) function is received
538 #if FH_AI_MaxPeripheralNumber > 0 // It is configurable in FH_DevicePeripherals.h
539 fh_ErrorInfo = FH_AI_RFCommunication (fh_RFCommunication_Message); // Process AI (Analog Input) function
540 #endif
541 break;
542 case RFCommunication_Function_PWMO: // If PWMO (PWM Output) function is received
543 #if FH_PWMO_MaxPeripheralNumber > 0 // It is configurable in FH_DevicePeripherals.h
544 fh_ErrorInfo = FH_PWMO_RFCommunication (fh_RFCommunication_Message); // Process PWMO (PWM Output) function
545 #endif
546 break;
547 case RFCommunication_Function_PWMI: // If PWMI (PWM Input) function is received
548 #if FH_PWMI_MaxPeripheralNumber > 0 // It is configurable in FH_DevicePeripherals.h
549 fh_ErrorInfo = FH_PWMI_RFCommunication (fh_RFCommunication_Message); // Process PWMI (PWM Input) function
550 #endif
551 break;
552 case RFCommunication_Function_UART: // If UART function is received
553 #if FH_UART_MaxPeripheralNumber > 0 // It is configurable in FH_DevicePeripherals.h
554 fh_ErrorInfo = FH_UART_RFCommunication (fh_RFCommunication_Message); // Process UART function
555 #endif
556 break;
557 case RFCommunication_Function_CAN: // If CAN function is received
558 #if FH_CAN_MaxPeripheralNumber > 0 // It is configurable in FH_DevicePeripherals.h
559 fh_ErrorInfo = FH_CAN_RFCommunication (fh_RFCommunication_Message); // Process CAN function
560 #endif
561 break;
562 default:
563 break;
564 }
565 }
566 else
567 {
568 }
569
570 return fh_ErrorInfo;
571}