XCP_SIM
xcp_daq.c
1 /*
2  * BlueParrot XCP
3  *
4  * (C) 2007-2022 by Christoph Schueler <github.com/Christoph2,
5  * cpu12.gems@googlemail.com>
6  *
7  * All Rights Reserved
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  *
23  * s. FLOSS-EXCEPTION.txt
24  */
25 
26 /*
27  *
28  * TODO: Cleanup DAQ configuration
29  *
30  */
31 
32 
33 #if defined(_WIN32)
34 #include <stdio.h>
35 #endif /* _WIN32 */
36 
38 #include "xcp.h"
39 #include "xcp_util.h"
42 /*
43 ** Private Parameters for now.
44 */
45 #define XCP_DAQ_QUEUE_SIZE (4)
46 #define XCP_DAQ_ENABLE_QUEUING XCP_ON
47 
48 /*
49 ** Local Types.
50 */
51 typedef struct {
52  uint8_t len;
53  uint8_t data[XCP_MAX_DTO];
55 
56 typedef enum tagXcpDaq_AllocResultType {
57  DAQ_ALLOC_OK,
58  DAQ_ALLOC_ERR
59 } XcpDaq_AllocResultType;
60 
61 typedef enum tagXcpDaq_AllocStateType {
62  XCP_ALLOC_IDLE,
63  XCP_AFTER_FREE_DAQ,
64  XCP_AFTER_ALLOC_DAQ,
65  XCP_AFTER_ALLOC_ODT,
66  XCP_AFTER_ALLOC_ODT_ENTRY
67 } XcpDaq_AllocStateType;
68 
69 typedef enum tagXcpDaq_AllocTransitionType {
70  XCP_CALL_FREE_DAQ,
71  XCP_CALL_ALLOC_DAQ,
72  XCP_CALL_ALLOC_ODT,
73  XCP_CALL_ALLOC_ODT_ENTRY
74 } XcpDaq_AllocTransitionype;
75 
76 typedef enum tagXcpDaq_ListTransitionType {
77  DAQ_LIST_TRANSITION_START,
78  DAQ_LIST_TRANSITION_STOP
79 } XcpDaq_ListTransitionType;
80 
81 #if XCP_DAQ_ENABLE_QUEUING == XCP_ON
82 typedef struct tagXcpDaq_QueueType {
83  uint8_t head;
84  uint8_t tail;
85  bool overload;
87 #endif /* XCP_DAQ_ENABLE_QUEUING */
88 
89 /*
90 ** Local Function-like Macros.
91 */
92 #define XCP_DAQ_MESSAGE_SIZE(msg) UINT16((((msg)->dlc) + sizeof(uint8_t)))
93 
94 /*
95 ** Local Function Prototypes.
96 */
97 void XcpDaq_PrintDAQDetails(void);
98 XCP_STATIC void XcpDaq_StartStopLists(XcpDaq_ListTransitionType transition);
99 XCP_STATIC void XcpDaq_InitMessageQueue(void);
100 #if XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_ON
101 XCP_STATIC bool
102 XcpDaq_AllocValidateTransition(XcpDaq_AllocTransitionype transition);
103 XCP_STATIC XcpDaq_ListIntegerType XcpDaq_GetDynamicListCount(void);
104 #endif /* XCP_DAQ_ENABLE_DYNAMIC_LISTS */
105 
106 #if XCP_DAQ_ENABLE_QUEUING == XCP_ON
107 bool XcpDaq_QueueEnqueue(uint16_t len, uint8_t const *data);
108 #endif /* XCP_DAQ_ENABLE_QUEUING */
109 
110 /*
111 ** Local Constants.
112 */
113 #if XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_ON
114 XCP_STATIC const uint8_t XcpDaq_AllocTransitionTable[5][4] = {
115  /* FREE_DAQ ALLOC_DAQ ALLOC_ODT ALLOC_ODT_ENTRY */
116  /* ALLOC_IDLE*/ {UINT8(DAQ_ALLOC_OK), UINT8(DAQ_ALLOC_ERR),
117  UINT8(DAQ_ALLOC_ERR), UINT8(DAQ_ALLOC_ERR)},
118  /* AFTER_FREE_DAQ */
119  {UINT8(DAQ_ALLOC_OK), UINT8(DAQ_ALLOC_OK), UINT8(DAQ_ALLOC_ERR),
120  UINT8(DAQ_ALLOC_ERR)},
121  /* AFTER_ALLOC_DAQ */
122  {UINT8(DAQ_ALLOC_OK), UINT8(DAQ_ALLOC_OK), UINT8(DAQ_ALLOC_OK),
123  UINT8(DAQ_ALLOC_ERR)},
124  /* AFTER_ALLOC_ODT */
125  {UINT8(DAQ_ALLOC_OK), UINT8(DAQ_ALLOC_ERR), UINT8(DAQ_ALLOC_OK),
126  UINT8(DAQ_ALLOC_OK)},
127  /* AFTER_ALLOC_ODT_ENTRY */
128  {UINT8(DAQ_ALLOC_OK), UINT8(DAQ_ALLOC_ERR), UINT8(DAQ_ALLOC_ERR),
129  UINT8(DAQ_ALLOC_OK)},
130 };
131 #endif /* XCP_DAQ_ENABLE_DYNAMIC_LISTS */
132 
133 /*
134 ** Local Variables.
135 */
136 
137 XCP_STATIC XcpDaq_EntityType XcpDaq_Entities[XCP_DAQ_MAX_DYNAMIC_ENTITIES];
138 
139 #if XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_ON
140 XCP_STATIC XcpDaq_AllocStateType XcpDaq_AllocState;
141 XCP_STATIC XcpDaq_ListStateType XcpDaq_ListState;
142 XCP_STATIC XcpDaq_ListConfigurationType XcpDaq_ListConfiguration;
143 XCP_STATIC XCP_DAQ_ENTITY_TYPE XcpDaq_EntityCount = (XCP_DAQ_ENTITY_TYPE)0;
144 XCP_STATIC XCP_DAQ_ENTITY_TYPE XcpDaq_ListCount = (XCP_DAQ_ENTITY_TYPE)0;
145 XCP_STATIC XCP_DAQ_ENTITY_TYPE XcpDaq_OdtCount = (XCP_DAQ_ENTITY_TYPE)0;
146 #endif /* XCP_DAQ_ENABLE_DYNAMIC_LISTS */
147 
148 #if XCP_DAQ_ENABLE_QUEUING == XCP_ON
149 XCP_STATIC XcpDaq_QueueType XcpDaq_Queue = {0};
150 XCP_STATIC XcpDaq_OdtType XcpDaq_QueueDTOs[XCP_DAQ_QUEUE_SIZE] = {0};
151 #endif /* XCP_DAQ_ENABLE_QUEUING */
152 
153 #if XCP_DAQ_ENABLE_MULTIPLE_DAQ_LISTS_PER_EVENT == XCP_OFF
154 XCP_STATIC uint8_t XcpDaq_ListForEvent[XCP_DAQ_MAX_EVENT_CHANNEL];
155 #else
156 #error XCP_DAQ_ENABLE_MULTIPLE_DAQ_LISTS_PER_EVENT option currently not supported
157 #endif /* XCP_DAQ_ENABLE_MULTIPLE_DAQ_LISTS_PER_EVENT */
158 
159 /*
160 **
161 ** Global Functions.
162 **
163 */
164 
165 /*
166 ** Dynamic DAQ related functions.
167 */
168 #if XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_ON
169 Xcp_ReturnType XcpDaq_Free(void) {
170  Xcp_ReturnType result = ERR_SUCCESS;
171 
172  XcpDaq_EntityCount = (XCP_DAQ_ENTITY_TYPE)0;
173  XcpDaq_ListCount = (XCP_DAQ_ENTITY_TYPE)0;
174  XcpDaq_OdtCount = (XCP_DAQ_ENTITY_TYPE)0;
175 
176 #if XCP_DAQ_ENABLE_MULTIPLE_DAQ_LISTS_PER_EVENT == XCP_OFF
177  XcpUtl_MemSet(XcpDaq_ListForEvent, UINT8(0),
178  UINT32(sizeof(XcpDaq_ListForEvent[0]) *
179  UINT8(XCP_DAQ_MAX_EVENT_CHANNEL)));
180 #endif /* XCP_DAQ_ENABLE_MULTIPLE_DAQ_LISTS_PER_EVENT */
181 
182  if (XcpDaq_AllocValidateTransition(XCP_CALL_FREE_DAQ)) {
183  XcpUtl_MemSet(XcpDaq_Entities, UINT8(0),
184  UINT32(sizeof(XcpDaq_EntityType) *
185  (XCP_DAQ_ENTITY_TYPE)XCP_DAQ_MAX_DYNAMIC_ENTITIES));
186  XcpDaq_AllocState = XCP_AFTER_FREE_DAQ;
187  } else {
188  result = ERR_SEQUENCE; /* Never touched; function always succeeds. */
189  }
190  return result;
191 }
192 
193 Xcp_ReturnType XcpDaq_Alloc(XcpDaq_ListIntegerType daqCount) {
194  XCP_DAQ_ENTITY_TYPE idx;
195  Xcp_ReturnType result = ERR_SUCCESS;
196 
197  if (!XcpDaq_AllocValidateTransition(XCP_CALL_ALLOC_DAQ)) {
198 #if XCP_DAQ_ENABLE_RESET_DYN_DAQ_CONFIG_ON_SEQUENCE_ERROR == XCP_ON
199  XcpDaq_Init();
200 #endif /* XCP_DAQ_ENABLE_RESET_DYN_DAQ_CONFIG_ON_SEQUENCE_ERROR */
201  result = ERR_SEQUENCE;
202  } else {
203  if ((XcpDaq_EntityCount + daqCount) <=
204  (XCP_DAQ_ENTITY_TYPE)XCP_DAQ_MAX_DYNAMIC_ENTITIES) {
205  XcpDaq_AllocState = XCP_AFTER_ALLOC_DAQ;
206  for (idx = XcpDaq_EntityCount; idx < (XcpDaq_EntityCount + daqCount);
207  ++idx) {
208  XcpDaq_Entities[idx].kind = UINT8(XCP_ENTITY_DAQ_LIST);
209  XcpDaq_Entities[idx].entity.daqList.numOdts = (XcpDaq_ODTIntegerType)0;
210  }
211  XcpDaq_ListCount += daqCount;
212  XcpDaq_EntityCount += daqCount;
213  } else {
214  result = ERR_MEMORY_OVERFLOW;
215  }
216  }
217  return result;
218 }
219 
220 Xcp_ReturnType XcpDaq_AllocOdt(XcpDaq_ListIntegerType daqListNumber,
221  XcpDaq_ODTIntegerType odtCount) {
222  XCP_DAQ_ENTITY_TYPE idx;
223  Xcp_ReturnType result = ERR_SUCCESS;
224 
225  if (!XcpDaq_AllocValidateTransition(XCP_CALL_ALLOC_ODT)) {
226 #if XCP_DAQ_ENABLE_RESET_DYN_DAQ_CONFIG_ON_SEQUENCE_ERROR == XCP_ON
227  XcpDaq_Init();
228 #endif /* XCP_DAQ_ENABLE_RESET_DYN_DAQ_CONFIG_ON_SEQUENCE_ERROR */
229  result = ERR_SEQUENCE;
230  } else {
231  if ((XcpDaq_EntityCount + odtCount) <=
232  (XCP_DAQ_ENTITY_TYPE)XCP_DAQ_MAX_DYNAMIC_ENTITIES) {
233  XcpDaq_AllocState = XCP_AFTER_ALLOC_ODT;
234  for (idx = XcpDaq_EntityCount; idx < (XcpDaq_EntityCount + odtCount);
235  ++idx) {
236  XcpDaq_Entities[idx].kind = UINT8(XCP_ENTITY_ODT);
237  }
238  XcpDaq_Entities[daqListNumber].entity.daqList.numOdts += odtCount;
239  XcpDaq_Entities[daqListNumber].entity.daqList.firstOdt =
240  XcpDaq_EntityCount;
241  XcpDaq_OdtCount += odtCount;
242  XcpDaq_EntityCount += odtCount;
243  } else {
244  result = ERR_MEMORY_OVERFLOW;
245  }
246  }
247  return result;
248 }
249 
250 Xcp_ReturnType
251 XcpDaq_AllocOdtEntry(XcpDaq_ListIntegerType daqListNumber,
252  XcpDaq_ODTIntegerType odtNumber,
253  XcpDaq_ODTEntryIntegerType odtEntriesCount) {
254  XCP_DAQ_ENTITY_TYPE idx;
255  XcpDaq_ODTIntegerType odt;
256  Xcp_ReturnType result = ERR_SUCCESS;
257 
258  if (!XcpDaq_AllocValidateTransition(XCP_CALL_ALLOC_ODT_ENTRY)) {
259 #if XCP_DAQ_ENABLE_RESET_DYN_DAQ_CONFIG_ON_SEQUENCE_ERROR == XCP_ON
260  XcpDaq_Init();
261 #endif /* XCP_DAQ_ENABLE_RESET_DYN_DAQ_CONFIG_ON_SEQUENCE_ERROR */
262  result = ERR_SEQUENCE;
263  } else {
264  if ((XcpDaq_EntityCount + odtEntriesCount) <=
265  (XCP_DAQ_ENTITY_TYPE)XCP_DAQ_MAX_DYNAMIC_ENTITIES) {
266  XcpDaq_AllocState = XCP_AFTER_ALLOC_ODT_ENTRY;
267  for (idx = XcpDaq_EntityCount;
268  idx < (XcpDaq_EntityCount + odtEntriesCount); ++idx) {
269  XcpDaq_Entities[idx].kind = UINT8(XCP_ENTITY_ODT_ENTRY);
270  }
271  odt = (XcpDaq_ODTIntegerType)(XcpDaq_Entities[daqListNumber]
272  .entity.daqList.firstOdt +
273  UINT16(odtNumber));
274  XcpDaq_Entities[odt].entity.odt.firstOdtEntry = XcpDaq_EntityCount;
275  XcpDaq_Entities[odt].entity.odt.numOdtEntries = odtEntriesCount;
276  XcpDaq_EntityCount += (XCP_DAQ_ENTITY_TYPE)odtEntriesCount;
277  } else {
278  result = ERR_MEMORY_OVERFLOW;
279  }
280  }
281  return result;
282 }
283 
284 XCP_STATIC bool
285 XcpDaq_AllocValidateTransition(XcpDaq_AllocTransitionype transition) {
286  /* printf("STATE: %u TRANSITION: %u\n", XcpDaq_AllocState, transition); */
287  if (XcpDaq_AllocTransitionTable[XcpDaq_AllocState][transition] ==
288  UINT8(DAQ_ALLOC_OK)) {
289  return (bool)XCP_TRUE;
290  } else {
291  return (bool)XCP_FALSE;
292  }
293 }
294 
295 XCP_STATIC XcpDaq_ListIntegerType XcpDaq_GetDynamicListCount(void) {
296  return (XcpDaq_ListIntegerType)XcpDaq_ListCount;
297 }
298 
299 XCP_DAQ_ENTITY_TYPE XcpDaq_GetDynamicDaqEntityCount(void) {
300  return XcpDaq_EntityCount;
301 }
302 #endif /* XCP_DAQ_ENABLE_DYNAMIC_LISTS */
303 
304 void XcpDaq_Init(void) {
305 #if XCP_DAQ_ENABLE_PREDEFINED_LISTS == XCP_ON
306  XcpDaq_ListIntegerType idx = 0;
307 
308  XcpDaq_StopAllLists();
309  XcpDaq_SetProcessorState(XCP_DAQ_STATE_STOPPED);
310 
311  for (idx = (XcpDaq_ListIntegerType)0; idx < XcpDaq_PredefinedListCount;
312  ++idx) {
313  XcpDaq_PredefinedListsState[idx].mode = UINT8(0);
314 #if XCP_DAQ_ENABLE_PRESCALER == XCP_ON
315  XcpDaq_PredefinedListsState[idx].prescaler = UINT8(1);
316  XcpDaq_PredefinedListsState[idx].counter = UINT8(0);
317 #endif /* XCP_DAQ_ENABLE_PRESCALER */
318  }
319 #endif /* XCP_DAQ_ENABLE_PREDEFINED_LISTS */
320 
321 #if XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_ON
322  XcpDaq_AllocState = XCP_ALLOC_IDLE;
323  (void)XcpDaq_Free();
324 #endif /* XCP_DAQ_ENABLE_DYNAMIC_LISTS */
325 
326 #if XCP_DAQ_ENABLE_QUEUING == XCP_ON
327  XcpDaq_QueueInit();
328 #endif
329 }
330 
331 XcpDaq_ODTEntryType *
332 XcpDaq_GetOdtEntry(XcpDaq_ListIntegerType daqListNumber,
333  XcpDaq_ODTIntegerType odtNumber,
334  XcpDaq_ODTEntryIntegerType odtEntryNumber) {
335  XcpDaq_ODTType const *odt = XCP_NULL;
336  XcpDaq_ODTIntegerType idx = 0;
337 
338  /* printf("XcpDaq_GetOdtEntry(()\n"); */
339 
340  /* TODO: Range checking. */
341  odt = XcpDaq_GetOdt(daqListNumber, odtNumber);
342  idx = (XcpDaq_ODTIntegerType)(odt->firstOdtEntry + UINT16(odtEntryNumber));
343 #if (XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_ON) && \
344  (XCP_DAQ_ENABLE_PREDEFINED_LISTS == XCP_OFF)
345  /* Dynamic DAQs only */
346  return &XcpDaq_Entities[idx].entity.odtEntry;
347 #elif (XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_OFF) && \
348  (XCP_DAQ_ENABLE_PREDEFINED_LISTS == XCP_ON)
349  return (XcpDaq_ODTEntryType *)&XcpDaq_PredefinedOdtEntries[idx];
350  /* Predefined DAQs only */
351 #elif (XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_ON) && \
352  (XCP_DAQ_ENABLE_PREDEFINED_LISTS == XCP_ON)
353  /* Dynamic and predefined DAQs */
354 #endif // XCP_DAQ_ENABLE_DYNAMIC_LISTS
355 }
356 
357 XcpDaq_ListConfigurationType const *
358 XcpDaq_GetListConfiguration(XcpDaq_ListIntegerType daqListNumber) {
359 #if XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_ON
360 
361 #endif // XCP_DAQ_ENABLE_DYNAMIC_LISTS
362 
363  // printf("XcpDaq_GetListConfiguration(%u)\n", daqListNumber);
364 #if (XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_ON) && \
365  (XCP_DAQ_ENABLE_PREDEFINED_LISTS == XCP_OFF)
366  /* Dynamic DAQs only */
367  XcpDaq_DynamicListType const *dl =
368  &XcpDaq_Entities[daqListNumber].entity.daqList;
369 
370  XcpDaq_ListConfiguration.firstOdt = dl->firstOdt;
371  XcpDaq_ListConfiguration.numOdts = dl->numOdts;
372 
373  return &XcpDaq_ListConfiguration;
374 #elif (XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_OFF) && \
375  (XCP_DAQ_ENABLE_PREDEFINED_LISTS == XCP_ON)
376  /* Predefined DAQs only */
377  return &XcpDaq_PredefinedLists[daqListNumber];
378 #elif (XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_ON) && \
379  (XCP_DAQ_ENABLE_PREDEFINED_LISTS == XCP_ON)
380  /* Dynamic and predefined DAQs */
381  return;
382 #endif
383 }
384 
385 XcpDaq_ListStateType *
386 XcpDaq_GetListState(XcpDaq_ListIntegerType daqListNumber) {
387 #if XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_ON
388 
389 #endif /* XCP_DAQ_ENABLE_DYNAMIC_LISTS */
390 
391  /* printf("XcpDaq_GetListState() number: %u\n", daqListNumber); */
392 #if (XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_ON) && \
393  (XCP_DAQ_ENABLE_PREDEFINED_LISTS == XCP_OFF)
394  /* Dynamic DAQs only */
395  return &XcpDaq_ListState;
396 
397 #elif (XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_OFF) && \
398  (XCP_DAQ_ENABLE_PREDEFINED_LISTS == XCP_ON)
399  /* Predefined DAQs only */
400  return &XcpDaq_PredefinedListsState[daqListNumber];
401 #elif (XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_ON) && \
402  (XCP_DAQ_ENABLE_PREDEFINED_LISTS == XCP_ON)
403  /* Dynamic and predefined DAQs */
404  if (daqListNumber >= XcpDaq_PredefinedListCount) {
405  XcpDaq_DynamicListType *dl = &XcpDaq_Entities[daqListNumber].entity.daqList;
406 
407  XcpDaq_ListState.mode = dl->mode;
408 
409  return &XcpDaq_ListState;
410  } else {
411  return &XcpDaq_PredefinedListsState[daqListNumber];
412  }
413 #endif
414 }
415 
416 void XcpDaq_SetPointer(XcpDaq_ListIntegerType daqListNumber,
417  XcpDaq_ODTIntegerType odtNumber,
418  XcpDaq_ODTEntryIntegerType odtEntryNumber) {
419  Xcp_StateType *Xcp_State = XCP_NULL;
420 
421  Xcp_State = Xcp_GetState();
422  Xcp_State->daqPointer.daqList = daqListNumber;
423  Xcp_State->daqPointer.odt = odtNumber;
424  Xcp_State->daqPointer.odtEntry = odtEntryNumber;
425 }
426 
427 bool XcpDaq_ValidateConfiguration(void) {
428 #if (XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_ON) && \
429  (XCP_DAQ_ENABLE_PREDEFINED_LISTS == XCP_OFF)
430  /* Dynamic DAQs only */
431  return (bool)((XcpDaq_EntityCount > (XCP_DAQ_ENTITY_TYPE)0) &&
432  (XcpDaq_ListCount > (XCP_DAQ_ENTITY_TYPE)0) &&
433  (XcpDaq_OdtCount > (XCP_DAQ_ENTITY_TYPE)0));
434 #elif (XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_OFF) && \
435  (XCP_DAQ_ENABLE_PREDEFINED_LISTS == XCP_ON)
436  /* Predefined DAQs only */
437  return (bool)XCP_TRUE;
438 #elif (XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_ON) && \
439  (XCP_DAQ_ENABLE_PREDEFINED_LISTS == XCP_ON)
440  /* Dynamic and predefined DAQs */
441 #endif
442 }
443 
444 XcpDaq_ListIntegerType XcpDaq_GetListCount(void) {
445 #if (XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_ON) && \
446  (XCP_DAQ_ENABLE_PREDEFINED_LISTS == XCP_OFF)
447  /* Dynamic DAQs only */
448  return XcpDaq_GetDynamicListCount();
449 #elif (XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_OFF) && \
450  (XCP_DAQ_ENABLE_PREDEFINED_LISTS == XCP_ON)
451  /* Predefined DAQs only */
452  return XcpDaq_PredefinedListCount;
453 #elif (XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_ON) && \
454  (XCP_DAQ_ENABLE_PREDEFINED_LISTS == XCP_ON)
455  /* Dynamic and predefined DAQs */
456  return XcpDaq_PredefinedListCount + XcpDaq_GetDynamicListCount();
457 #endif
458 }
459 
460 bool XcpDaq_ValidateList(XcpDaq_ListIntegerType daqListNumber) {
461  XcpDaq_ListConfigurationType const *daqList = XCP_NULL;
462  XcpDaq_ODTType const *odt = XCP_NULL;
463  bool result = (bool)XCP_TRUE;
464  XcpDaq_ODTIntegerType numOdts = 0;
465  uint8_t idx = 0;
466 
467  if (daqListNumber > (XcpDaq_GetListCount() - UINT16(1))) {
468  result = (bool)XCP_FALSE;
469  } else {
470  daqList = XcpDaq_GetListConfiguration(daqListNumber);
471  numOdts = daqList->numOdts;
472  if (numOdts == UINT8(0)) {
473  result = (bool)XCP_FALSE;
474  } else {
475  result = (bool)XCP_FALSE;
476  for (idx = UINT8(0); idx < numOdts; ++idx) {
477  odt = XcpDaq_GetOdt(daqListNumber, idx);
478  if (odt->numOdtEntries != UINT8(0)) {
479  result = (bool)XCP_TRUE;
480  break;
481  }
482  }
483  }
484  }
485  return result;
486 }
487 
488 bool XcpDaq_ValidateOdtEntry(XcpDaq_ListIntegerType daqListNumber,
489  XcpDaq_ODTIntegerType odtNumber,
490  XcpDaq_ODTEntryIntegerType odtEntry) {
491  XcpDaq_ListConfigurationType const *daqList = XCP_NULL;
492  XcpDaq_ODTType const *odt = XCP_NULL;
493  bool result = (bool)XCP_TRUE;
494 
495  if (daqListNumber > (XcpDaq_GetListCount() - UINT16(1))) {
496  result = (bool)XCP_FALSE;
497  } else {
498  daqList = XcpDaq_GetListConfiguration(daqListNumber);
499  if (odtNumber > (daqList->numOdts - (XcpDaq_ODTIntegerType)1)) {
500  result = (bool)XCP_FALSE;
501  } else {
502  odt = XcpDaq_GetOdt(daqListNumber, odtNumber);
503  if (odtEntry > (odt->numOdtEntries - (XcpDaq_ODTEntryIntegerType)1)) {
504  result = (bool)XCP_FALSE;
505  }
506  }
507  }
508  return result;
509 }
510 
511 XcpDaq_EventType const *
512 XcpDaq_GetEventConfiguration(uint16_t eventChannelNumber) {
513  if (eventChannelNumber >= UINT8(XCP_DAQ_MAX_EVENT_CHANNEL)) {
514  return (XcpDaq_EventType const *)XCP_NULL;
515  }
516  return &XcpDaq_Events[eventChannelNumber];
517 }
518 
519 void XcpDaq_AddEventChannel(XcpDaq_ListIntegerType daqListNumber,
520  uint16_t eventChannelNumber) {
521 #if XCP_DAQ_ENABLE_MULTIPLE_DAQ_LISTS_PER_EVENT == XCP_OFF
522  XcpDaq_ListForEvent[eventChannelNumber] = daqListNumber;
523 #endif /* XCP_DAQ_ENABLE_MULTIPLE_DAQ_LISTS_PER_EVENT */
524 }
525 
530 void XcpDaq_TriggerEvent(uint8_t eventChannelNumber) {
531  Xcp_StateType const *state = XCP_NULL;
532  XcpDaq_ListIntegerType daqListNumber = 0;
533  XcpDaq_ODTIntegerType odtIdx = 0;
534  XcpDaq_ODTIntegerType pid = 0;
535  XcpDaq_ODTEntryIntegerType odtEntryIdx = 0;
536  XcpDaq_ODTType const *odt = XCP_NULL;
537  XcpDaq_ODTEntryType *entry = XCP_NULL;
538  XcpDaq_ListConfigurationType const *listConf = XCP_NULL;
539  uint16_t offset = UINT16(0);
540  uint32_t timestamp = UINT32(0);
541  uint8_t data[XCP_MAX_DTO] = {0};
542 
543  state = Xcp_GetState();
544  if (state->daqProcessor.state != XCP_DAQ_STATE_RUNNING) {
545  return;
546  }
547  if (eventChannelNumber >= UINT8(XCP_DAQ_MAX_EVENT_CHANNEL)) {
548  return;
549  }
550 
551  timestamp = XcpHw_GetTimerCounter();
552 
553 #if XCP_DAQ_ENABLE_MULTIPLE_DAQ_LISTS_PER_EVENT == XCP_OFF
554  daqListNumber = XcpDaq_ListForEvent[eventChannelNumber];
555 #endif /* XCP_DAQ_ENABLE_MULTIPLE_DAQ_LISTS_PER_EVENT */
556 
557  if (!XcpDaq_GetFirstPid(daqListNumber, &pid)) {
558  return;
559  }
560  listConf = XcpDaq_GetListConfiguration(daqListNumber);
561  for (odtIdx = (XcpDaq_ODTIntegerType)0; odtIdx < listConf->numOdts;
562  ++odtIdx) {
563  offset = UINT16(0);
564  odt = XcpDaq_GetOdt(daqListNumber, odtIdx);
565 
566  data[0] = pid; /* Absolute ODT number. */
567  offset += UINT16(1);
568 
569  for (odtEntryIdx = (XcpDaq_ODTEntryIntegerType)0;
570  odtEntryIdx < odt->numOdtEntries; ++odtEntryIdx) {
571  entry = XcpDaq_GetOdtEntry(daqListNumber, odtIdx, odtEntryIdx);
572  // printf("\tAddress: 0x%08x Length: %d\n", entry->mta.address,
573  // entry->length);
574  if (odtEntryIdx == (XcpDaq_ODTEntryIntegerType)0) {
575  }
576  XCP_ASSERT_LE(entry->length, (unsigned int)(XCP_MAX_DTO - offset));
577  XcpDaq_CopyMemory(&data[offset], (void *)entry->mta.address,
578  entry->length);
579  offset += entry->length;
580  }
581  pid++;
582  XcpDaq_QueueEnqueue(offset, data);
583  // XcpUtl_Hexdump(data, offset);
584  }
585  XcpHw_TransmitDtos();
586 }
587 
594 void XcpDaq_CopyMemory(void *dst, void const *src, uint32_t len) {
595  XcpUtl_MemCopy(dst, src, len);
596 }
597 
598 void XcpDaq_GetProperties(uint8_t *properties) {
599  *properties = UINT8(0);
600 #if XCP_DAQ_ENABLE_PRESCALER == XCP_ON
601  *properties |= XCP_DAQ_PROP_PRESCALER_SUPPORTED;
602 #endif /*XCP_DAQ_ENABLE_PRESCALER */
603 
604 #if (XCP_DAQ_CONFIG_TYPE == XCP_DAQ_CONFIG_TYPE_NONE) || \
605  (XCP_DAQ_CONFIG_TYPE == XCP_DAQ_CONFIG_TYPE_STATIC)
606  *properties |= UINT8(XCP_DAQ_CONFIG_TYPE_STATIC);
607 #elif XCP_DAQ_CONFIG_TYPE == XCP_DAQ_CONFIG_TYPE_DYNAMIC
608  *properties |= UINT8(XCP_DAQ_CONFIG_TYPE_NONE);
609 #endif
610 }
611 
612 void XcpDaq_SetProcessorState(XcpDaq_ProcessorStateType state) {
613  Xcp_StateType *stateVar = XCP_NULL;
614 
615  stateVar = Xcp_GetState();
616  XCP_DAQ_ENTER_CRITICAL();
617  stateVar->daqProcessor.state = state;
618  XCP_DAQ_LEAVE_CRITICAL();
619 }
620 
621 void XcpDaq_StartSelectedLists(void) {
622  XcpDaq_StartStopLists(DAQ_LIST_TRANSITION_START);
623 }
624 
625 void XcpDaq_StopSelectedLists(void) {
626  XcpDaq_StartStopLists(DAQ_LIST_TRANSITION_STOP);
627 }
628 
629 void XcpDaq_StopAllLists(void) {
630  XcpDaq_StartStopLists(DAQ_LIST_TRANSITION_STOP);
631 }
632 
633 /*
634 ** Local Functions.
635 */
636 XcpDaq_ODTType const *XcpDaq_GetOdt(XcpDaq_ListIntegerType daqListNumber,
637  XcpDaq_ODTIntegerType odtNumber) {
638  XcpDaq_ListConfigurationType const *dl = XCP_NULL;
639  XcpDaq_ODTIntegerType idx = 0;
640 
641  dl = XcpDaq_GetListConfiguration(daqListNumber);
642  idx = (XcpDaq_ODTIntegerType)dl->firstOdt + odtNumber;
643 #if (XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_ON) && \
644  (XCP_DAQ_ENABLE_PREDEFINED_LISTS == XCP_OFF)
645  /* Dynamic DAQs only */
646  return &XcpDaq_Entities[idx].entity.odt;
647 #elif (XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_OFF) && \
648  (XCP_DAQ_ENABLE_PREDEFINED_LISTS == XCP_ON)
649  /* Predefined DAQs only */
650  return &XcpDaq_PredefinedOdts[idx];
651 #elif (XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_ON) && \
652  (XCP_DAQ_ENABLE_PREDEFINED_LISTS == XCP_ON)
653  /* Dynamic and predefined DAQs */
654 #endif
655 }
656 
657 XCP_STATIC void XcpDaq_StartStopLists(XcpDaq_ListTransitionType transition) {
658  XcpDaq_ListIntegerType idx = 0;
659  XcpDaq_ListStateType *entry = XCP_NULL;
660 
661  for (idx = (XcpDaq_ListIntegerType)0; idx < XcpDaq_GetListCount(); ++idx) {
662  entry = XcpDaq_GetListState(idx);
663  if ((entry->mode & XCP_DAQ_LIST_MODE_SELECTED) ==
664  XCP_DAQ_LIST_MODE_SELECTED) {
665  if (transition == DAQ_LIST_TRANSITION_START) {
666  entry->mode |= XCP_DAQ_LIST_MODE_STARTED;
667  /* printf("Started DAQ list #%u\n", idx); */
668  } else if (transition == DAQ_LIST_TRANSITION_STOP) {
669  entry->mode &= UINT8(~XCP_DAQ_LIST_MODE_STARTED);
670  /* printf("Stopped DAQ list #%u\n", idx); */
671  } else {
672  /* Do nothing (to keep MISRA happy). */
673  }
674  /*
675  * The slave has to reset the SELECTED flag in the mode at
676  * GET_DAQ_LIST_MODE as soon as the related START_STOP_SYNCH or
677  * SET_REQUEST have been acknowledged.
678  */
679  entry->mode &= UINT8(~XCP_DAQ_LIST_MODE_SELECTED);
680  }
681  }
682 }
683 
684 bool XcpDaq_GetFirstPid(XcpDaq_ListIntegerType daqListNumber,
685  XcpDaq_ODTIntegerType *firstPID) {
686  XcpDaq_ListIntegerType listIdx = 0;
687  XcpDaq_ListConfigurationType const *daqList = XCP_NULL;
688  bool result = (bool)XCP_TRUE;
689  XcpDaq_ODTIntegerType tmp = (XcpDaq_ODTIntegerType)0;
690 
691  if (daqListNumber > (XcpDaq_GetListCount() - UINT16(1))) {
692  result = (bool)XCP_FALSE;
693  } else {
694  for (listIdx = UINT16(0); listIdx < daqListNumber; ++listIdx) {
695  daqList = XcpDaq_GetListConfiguration(listIdx);
696  tmp += daqList->numOdts;
697  }
698  }
699  *firstPID = tmp;
700  return result;
701 }
702 
703 /*
704 ** Debugging / Testing interface.
705 */
706 #if XCP_BUILD_TYPE == XCP_DEBUG_BUILD
707 
708 void XcpDaq_GetCounts(XCP_DAQ_ENTITY_TYPE *entityCount,
709  XCP_DAQ_ENTITY_TYPE *listCount,
710  XCP_DAQ_ENTITY_TYPE *odtCount) {
711  *entityCount = XcpDaq_EntityCount;
712  *listCount = XcpDaq_ListCount;
713  *odtCount = XcpDaq_OdtCount;
714 }
715 
716 uint16_t XcpDaq_TotalDynamicEntityCount(void) {
717  return UINT16(XCP_DAQ_MAX_DYNAMIC_ENTITIES);
718 }
719 
720 XcpDaq_EntityType *XcpDaq_GetDynamicEntities(void) {
721  return &XcpDaq_Entities[0];
722 }
723 
724 XcpDaq_EntityType *XcpDaq_GetDynamicEntity(uint16_t num) {
725  return &XcpDaq_Entities[num];
726 }
727 
728 void XcpDaq_QueueGetVar(XcpDaq_QueueType *var) {
729  XcpUtl_MemCopy(var, &XcpDaq_Queue, sizeof(XcpDaq_QueueType));
730 }
731 
732 #endif /* XCP_BUILD_TYPE */
733 
734 //#if XCP_DAQ_ENABLE_DYNAMIC_LISTS == XCP_ON
735 
736 #if XCP_DAQ_ENABLE_QUEUING == XCP_ON
737 void XcpDaq_QueueInit(void) {
738  uint8_t idx;
739 
740  XcpDaq_Queue.head = XcpDaq_Queue.tail = UINT8(0);
741  XcpDaq_Queue.overload = (bool)XCP_FALSE;
742  for (idx = UINT8(0); idx < UINT8(XCP_DAQ_QUEUE_SIZE); ++idx) {
743  XcpUtl_ZeroMem(&XcpDaq_QueueDTOs[idx], sizeof(Xcp_PduType));
744  }
745 }
746 
747 XCP_STATIC bool XcpDaq_QueueFull(void) {
748  return ((XcpDaq_Queue.head + UINT8(1)) % UINT8(XCP_DAQ_QUEUE_SIZE + 1)) ==
749  XcpDaq_Queue.tail;
750 }
751 
752 bool XcpDaq_QueueEmpty(void) { return XcpDaq_Queue.head == XcpDaq_Queue.tail; }
753 
754 bool XcpDaq_QueueEnqueue(uint16_t len, uint8_t const *data) {
755  if (XcpDaq_QueueFull()) {
756  XcpDaq_Queue.overload = (bool)XCP_TRUE;
757  return (bool)XCP_FALSE;
758  }
759 
760  XcpDaq_QueueDTOs[XcpDaq_Queue.head].len = len;
761 
762  XCP_ASSERT_LE(len, XCP_MAX_DTO);
763  XcpUtl_MemCopy(XcpDaq_QueueDTOs[XcpDaq_Queue.head].data, data, len);
764  XcpDaq_Queue.head =
765  (XcpDaq_Queue.head + UINT8(1)) % UINT8(XCP_DAQ_QUEUE_SIZE + 1);
766  return (bool)XCP_TRUE;
767 }
768 
769 bool XcpDaq_QueueDequeue(uint16_t *len, uint8_t *data) {
770  uint16_t dto_len;
771 
772  if (XcpDaq_QueueEmpty()) {
773  return (bool)XCP_FALSE;
774  }
775  dto_len = XcpDaq_QueueDTOs[XcpDaq_Queue.tail].len;
776  XCP_ASSERT_LE(dto_len, XCP_MAX_DTO);
777  *len = dto_len;
778  XcpUtl_MemCopy(data, XcpDaq_QueueDTOs[XcpDaq_Queue.tail].data, dto_len);
779  XcpDaq_Queue.tail =
780  (XcpDaq_Queue.tail + UINT8(1)) % UINT8(XCP_DAQ_QUEUE_SIZE + 1);
781  return (bool)XCP_TRUE;
782 }
783 //#endif /* XCP_DAQ_ENABLE_DYNAMIC_LISTS */
784 #endif /* XCP_DAQ_ENABLE_QUEUING */