SCOM Serial Communication Protocol  0.5.2
scom_frame.c
Go to the documentation of this file.
1 
11 #define HAL_LOG_CHANNEL SCOM
12 #define HAL_LOG_SUBCHANNEL FRAME
13 
14 #include "scom_frame.h"
15 #include "scom_crc.h"
16 #include "hal.h"
17 // --------------------------------------------------------------------------------------
18 // SCOMFrame_GetTotalFrameSize
19 // --------------------------------------------------------------------------------------
20 uint16_t SCOMFrame_GetTotalFrameSize(const SCOMFrame* const frame) {
21  HAL_ASSERT_AND_EXECUTE(frame != NULL) {
22  // Calculate total frame size which is a sum of all frame fields
23  uint16_t size = sizeof(frame->sync) + sizeof(frame->sof) + SCOMFrame_GetPacketControlSize();
24 
25  // for multiframes add multiframe descriptor size
26  if (SCOMFrame_IsMultiframe(frame)){
27  size += sizeof(frame->payload.multiframe.multi_id) + sizeof(frame->payload.multiframe.offset)
28  + sizeof(frame->payload.multiframe.total_size);
29  }
30 
31  // Include payload size
32  size += frame->size;
33  return size;
34  }
35  return 0;
36 } /* SCOMFrame_GetTotalFrameSize */
37 
38 
39 // --------------------------------------------------------------------------------------
40 // SCOMFrame_SetType
41 // --------------------------------------------------------------------------------------
42 bool SCOMFrame_SetType(SCOMFrame* const frame, const uint8_t type) {
43  HAL_ASSERT_AND_EXECUTE(frame != NULL) {
44  HAL_ASSERT_AND_EXECUTE(type <= 240) {
45  frame->type = type;
46  return true;
47  }
48  }
49  return false;
50 } /* SCOMFrame_SetType */
51 
52 
53 // --------------------------------------------------------------------------------------
54 // SCOMFrame_GetType
55 // --------------------------------------------------------------------------------------
56 uint8_t SCOMFrame_GetType(const SCOMFrame* const frame) {
57  HAL_ASSERT_AND_EXECUTE(frame != NULL) {
58  return frame->type;
59  }
60  return 0xff;
61 } /* SCOMFrame_GetType */
62 
63 
64 // --------------------------------------------------------------------------------------
65 // SCOMFrame_SetPriority
66 // --------------------------------------------------------------------------------------
67 bool SCOMFrame_SetPriority(SCOMFrame* const frame, const uint8_t priority) {
68  HAL_ASSERT_AND_EXECUTE(frame != NULL) {
69  HAL_ASSERT_AND_EXECUTE(priority <= 7) {
70  frame->ctrl &= ~SCOM_FRAME_CTRL_FRAME_PRIORITY_MASK; // Clear priority
71  frame->ctrl |= priority << 4; //set new priority
72  return true;
73  }
74  }
75  return false;
76 } /* SCOMFrame_SetPriority */
77 
78 
79 // --------------------------------------------------------------------------------------
80 // SCOMFrame_GetPriority
81 // --------------------------------------------------------------------------------------
82 uint8_t SCOMFrame_GetPriority(const SCOMFrame* const frame) {
83  HAL_ASSERT_AND_EXECUTE(frame != NULL) {
84  return (frame->ctrl & SCOM_FRAME_CTRL_FRAME_PRIORITY_MASK) >> 4;
85  }
86  return 0xff;
87 } /* SCOMFrame_GetPriority */
88 
89 
90 // --------------------------------------------------------------------------------------
91 // SCOMFrame_SetFrameNumber
92 // --------------------------------------------------------------------------------------
93 bool SCOMFrame_SetFrameNumber(SCOMFrame* const frame, const uint8_t number) {
94  HAL_ASSERT_AND_EXECUTE(frame != NULL) {
95  HAL_ASSERT_AND_EXECUTE(number <= SCOM_FRAME_CTRL_FRAME_NUMBER_MASK) {
96  frame->ctrl &= ~SCOM_FRAME_CTRL_FRAME_NUMBER_MASK; // Clear old number
97  frame->ctrl |= number; // Set new number
98  return true;
99  }
100  }
101  return false;
102 } /* SCOMFrame_SetFrameNumber */
103 
104 
105 // --------------------------------------------------------------------------------------
106 // SCOMFrame_GetFrameNumber
107 // --------------------------------------------------------------------------------------
108 uint8_t SCOMFrame_GetFrameNumber(const SCOMFrame * const frame) {
109  HAL_ASSERT_AND_EXECUTE(frame != NULL) {
110  return frame->ctrl & SCOM_FRAME_CTRL_FRAME_NUMBER_MASK;
111  }
112  return 0xff;
113 } /* SCOMFrame_GetFrameNumber */
114 
115 
116 // --------------------------------------------------------------------------------------
117 // SCOMFrame_SetPayloadSize
118 // --------------------------------------------------------------------------------------
119 bool SCOMFrame_SetPayloadSize(SCOMFrame* const frame, const uint8_t size) {
120  HAL_ASSERT_AND_EXECUTE(frame != NULL) {
121  HAL_ASSERT_AND_EXECUTE(size <= SCOM_MAX_DATA_LENGTH) {
122  frame->size = size;
123  return true;
124  }
125  }
126  return false;
127 } /* SCOMFrame_SetPayloadSize */
128 
129 
130 // --------------------------------------------------------------------------------------
131 // SCOMFrame_GetPayloadSize
132 // --------------------------------------------------------------------------------------
133 uint8_t SCOMFrame_GetPayloadSize(const SCOMFrame* const frame) {
134  HAL_ASSERT_AND_EXECUTE(frame != NULL) {
135  return frame->size;
136  }
137  return 0xff;
138 } /* SCOMFrame_GetPayloadSize */
139 
140 
141 // --------------------------------------------------------------------------------------
142 // SCOMFrame_GetPayloadPtr
143 // --------------------------------------------------------------------------------------
144 uint8_t* SCOMFrame_GetPayloadPtr(const SCOMFrame* const frame) {
145  HAL_ASSERT_AND_EXECUTE(frame != NULL) {
146  return (frame->ctrl & SCOM_FRAME_CTRL_MULTI_ID_MASK) ? (uint8_t*)frame->payload.multiframe.data : (uint8_t*)frame->payload.singleframe.data;
147  }
148  return NULL;
149 } /* SCOMFrame_GetPayloadPtr */
150 
151 
152 // --------------------------------------------------------------------------------------
153 // SCOMFrame_GetTotalPayloadSize
154 // --------------------------------------------------------------------------------------
155 uint32_t SCOMFrame_GetTotalPayloadSize(const SCOMFrame* const frame) {
156  HAL_ASSERT_AND_EXECUTE(frame != NULL) {
157  return (frame->ctrl & SCOM_FRAME_CTRL_MULTI_ID_MASK) ? frame->payload.multiframe.total_size : (uint32_t)frame->size;
158  }
159  return 0;
160 } /* SCOMFrame_GetTotalPayloadSize */
161 
162 
163 // --------------------------------------------------------------------------------------
164 // SCOMFrame_GetMultiId
165 // --------------------------------------------------------------------------------------
166 uint32_t SCOMFrame_GetMultiId(const SCOMFrame* const frame) {
167  HAL_ASSERT_AND_EXECUTE(frame != NULL) {
168  if (frame->ctrl & SCOM_FRAME_CTRL_MULTI_ID_MASK) {
169  return frame->payload.multiframe.multi_id; // if this is a mluti-frame
170  }
171  }
172  return 0;
173 } /* SCOMFrame_GetMultiId */
174 
175 
176 // --------------------------------------------------------------------------------------
177 // SCOMFrame_GetMultiOffset
178 // --------------------------------------------------------------------------------------
179 uint32_t SCOMFrame_GetMultiOffset(const SCOMFrame* const frame) {
180  HAL_ASSERT_AND_EXECUTE(frame != NULL) {
181  if (frame->ctrl & SCOM_FRAME_CTRL_MULTI_ID_MASK) {
182  return frame->payload.multiframe.offset; // if this is a mluti-frame
183  }
184  }
185  return 0;
186 } /* SCOMFrame_GetMultiOffset */
187 
188 
189 // --------------------------------------------------------------------------------------
190 // SCOMFrame_SetAcknowledgement
191 // --------------------------------------------------------------------------------------
192 bool SCOMFrame_SetAcknowledgement(SCOMFrame* const frame, const bool ack) {
193  HAL_ASSERT_AND_EXECUTE(frame != NULL) {
194  if (true == ack) {
195  frame->ctrl &= ~(SCOM_FRAME_CTRL_NOACK_MASK);
196  } else {
198  }
199  return true;
200  }
201  return false;
202 } /* SCOMFrame_SetAcknowledgement */
203 
204 
205 // --------------------------------------------------------------------------------------
206 // SCOMFrame_IsMultiframe
207 // --------------------------------------------------------------------------------------
208 bool SCOMFrame_IsMultiframe(const SCOMFrame* const frame) {
209  HAL_ASSERT_AND_EXECUTE(frame != NULL) {
210  if (frame->ctrl & SCOM_FRAME_CTRL_MULTI_ID_MASK) {
211  return true;
212  }
213  }
214  return false;
215 } /* SCOMFrame_IsMultiframe */
216 
217 
218 // --------------------------------------------------------------------------------------
219 // SCOMFrame_IsAcknowledged
220 // --------------------------------------------------------------------------------------
221 bool SCOMFrame_IsAcknowledged(const SCOMFrame* const frame) {
222  HAL_ASSERT_AND_EXECUTE(frame != NULL) {
223  if (frame->ctrl & SCOM_FRAME_CTRL_NOACK_MASK) {
224  return false;
225  }
226  }
227  return true;
228 } /* SCOMFrame_IsAcknowledged */
229 
230 
231 // --------------------------------------------------------------------------------------
232 // SCOMFrame_CalculateCRC
233 // --------------------------------------------------------------------------------------
234 uint16_t SCOMFrame_CalculateCRC(const SCOMFrame* const frame) {
235  HAL_ASSERT_AND_EXECUTE(frame != NULL) {
236  uint16_t crc = CRC16_InitCRC();
237  crc = CRC16_UpdateCRC_Byte(frame->ctrl, crc);
238  crc = CRC16_UpdateCRC_Byte(frame->type, crc);
239  crc = CRC16_UpdateCRC_Byte(frame->size, crc);
240 
241  const uint8_t* const begin = frame->payload.singleframe.data;
242  const uint8_t* const end = begin + frame->size;
243 
244  for(const uint8_t* it = begin; it < end; ++it) {
245  crc = CRC16_UpdateCRC_Byte(*it, crc);
246  }
247  return crc;
248  }
249  return 0;
250 } /* SCOMFrame_CalculateCRC */
uint32_t SCOMFrame_GetMultiOffset(const SCOMFrame *const frame)
Definition: scom_frame.c:179
uint8_t sync
synchronization field: always 0xFF
bool SCOMFrame_IsAcknowledged(const SCOMFrame *const frame)
Definition: scom_frame.c:221
SCOM version record.
Definition: scom.h:81
bool SCOMFrame_SetPayloadSize(SCOMFrame *const frame, const uint8_t size)
Definition: scom_frame.c:119
#define SCOM_FRAME_CTRL_NOACK_MASK
Definition: scom_frame.h:40
#define SCOM_FRAME_CTRL_FRAME_NUMBER_MASK
Definition: scom_frame.h:39
bool SCOMFrame_SetPriority(SCOMFrame *const frame, const uint8_t priority)
Definition: scom_frame.c:67
uint8_t SCOMFrame_GetPayloadSize(const SCOMFrame *const frame)
Definition: scom_frame.c:133
#define CRC16_UpdateCRC_Byte
Definition of CRC16 byte update function.
Definition: scom_crc.h:23
bool SCOMFrame_SetType(SCOMFrame *const frame, const uint8_t type)
Definition: scom_frame.c:42
uint8_t * SCOMFrame_GetPayloadPtr(const SCOMFrame *const frame)
Definition: scom_frame.c:144
Definition of SCOM CRC functions.
uint8_t SCOMFrame_GetType(const SCOMFrame *const frame)
Definition: scom_frame.c:56
bool SCOMFrame_SetAcknowledgement(SCOMFrame *const frame, const bool ack)
Definition: scom_frame.c:192
uint8_t type
frame type field
#define SCOM_FRAME_CTRL_MULTI_ID_MASK
Definition: scom_frame.h:42
uint8_t size
frame type field
Definition: scom_frame.h:59
struct HAL_PACKED::@1::@3 multiframe
payload definition for a multi frame
uint32_t SCOMFrame_GetMultiId(const SCOMFrame *const frame)
Definition: scom_frame.c:166
uint8_t ctrl
frame control field
#define SCOM_MAX_DATA_LENGTH
Definition: doxygen.h:636
uint8_t SCOMFrame_GetPriority(const SCOMFrame *const frame)
Definition: scom_frame.c:82
#define CRC16_InitCRC
Definition of CRC16 initialization function.
Definition: scom_crc.h:17
uint16_t SCOMFrame_CalculateCRC(const SCOMFrame *const frame)
Definition: scom_frame.c:234
uint8_t SCOMFrame_GetFrameNumber(const SCOMFrame *const frame)
Definition: scom_frame.c:108
uint32_t SCOMFrame_GetTotalPayloadSize(const SCOMFrame *const frame)
Definition: scom_frame.c:155
union HAL_PACKED::@1 payload
payload field
struct HAL_PACKED::@1::@2 singleframe
payload definition for a single frame
bool SCOMFrame_IsMultiframe(const SCOMFrame *const frame)
Definition: scom_frame.c:208
#define SCOM_FRAME_CTRL_FRAME_PRIORITY_MASK
Definition: scom_frame.h:41
uint8_t sof
synchronization field: always 0xFF
Definition: scom_frame.h:56
bool SCOMFrame_SetFrameNumber(SCOMFrame *const frame, const uint8_t number)
Definition: scom_frame.c:93
SCOM frame definition.
uint16_t SCOMFrame_GetTotalFrameSize(const SCOMFrame *const frame)
Definition: scom_frame.c:20