foxBMS - Unit Tests  1.5.1
The foxBMS Unit Tests API Documentation
can.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2023, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice, this
12  * list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  *
18  * 3. Neither the name of the copyright holder nor the names of its
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * We kindly request you to use one or more of the following phrases to refer to
34  * foxBMS in your hardware, software, documentation or advertising materials:
35  *
36  * - ″This product uses parts of foxBMS®″
37  * - ″This product includes parts of foxBMS®″
38  * - ″This product is derived from foxBMS®″
39  *
40  */
41 
42 /**
43  * @file can.c
44  * @author foxBMS Team
45  * @date 2019-12-04 (date of creation)
46  * @updated 2023-02-23 (date of last update)
47  * @version v1.5.1
48  * @ingroup DRIVERS
49  * @prefix CAN
50  *
51  * @brief Driver for the CAN module
52  *
53  * @details Implementation of the CAN Interrupts, initialization, buffers,
54  * receive and transmit interfaces.
55  */
56 
57 /*========== Includes =======================================================*/
58 #include "general.h"
59 
60 #include "can.h"
61 
62 #include "HL_het.h"
63 #include "HL_reg_system.h"
64 
65 #include "can_helper.h"
66 #include "database.h"
67 #include "diag.h"
68 #include "ftask.h"
69 #include "pex.h"
70 
71 #include <stdbool.h>
72 #include <stdint.h>
73 
74 /*========== Macros and Definitions =========================================*/
75 /** lower limit of timestamp counts for a valid CAN timing */
76 #define CAN_TIMING_LOWER_LIMIT_COUNTS (95u)
77 
78 /** upper limit of timestamp counts for a valid CAN timing */
79 #define CAN_TIMING_UPPER_LIMIT_COUNTS (105u)
80 
81 /** return value of function canGetData if no data was lost during reception */
82 #define CAN_HAL_RETVAL_NO_DATA_LOST (1u)
83 
84 /**
85  * IF2ARB register configuration
86  *
87  * Bits 28-0 ID: Message identifier
88  * ID[28:0] 29-bit Identifier ("Extended Frame").
89  * ID[28:18] 11-bit Identifier ("Standard Frame").
90  */
91 /** ID shift for standard identifier */
92 #define CAN_IF2ARB_STANDARD_IDENTIFIER_SHIFT (18u)
93 /** ID shift for extended identifier */
94 #define CAN_IF2ARB_EXTENDED_IDENTIFIER_SHIFT (0u)
95 
96 /* Bit 29 Dir: Message direction
97  * 0 Direction = Receive: On Tx Request, a Remote Frame with the identifier of this message object is
98  * transmitted. On receiving a Data Frame with a matching identifier, this message is stored in this
99  * message object.
100  * 1 Direction = Transmit: On TxRequest, the respective message object is transmitted as a Data
101  * Frame. On receiving a Remote Frame with a matching identifier, the TxRequest bit of this message
102  * object is set (if RmtEn = 1).
103  */
104 /** IF2ARB set TX direction */
105 #define CAN_IF2ARB_SET_TX_DIRECTION ((uint32)1u << 29u)
106 /* Bit 30 - Xtd: Extended identifier
107  * 0 The 11-bit ("standard") identifier is used for this message object
108  * 1 The 29-bit ("extended") identifier is used for this message object
109  */
110 /** IF2ARB use standard identifier */
111 #define CAN_IF2ARB_USE_STANDARD_IDENTIFIER ((uint32)0u << 30u)
112 /** IF2ARB use extended identifier */
113 #define CAN_IF2ARB_USE_EXTENDED_IDENTIFIER ((uint32)1u << 30u)
114 
115 /** Range of mailboxes that are explicitly configured for the reception of
116  * messages with extended identifiers. */ /**@{*/
117 #define CAN_LOWEST_MAILBOX_FOR_EXTENDED_IDENTIFIERS (61u)
118 #define CAN_HIGHEST_MAILBOX_FOR_EXTENDED_IDENTIFIERS (64u)
119 /**@}*/
120 
123  "Lower mailbox number must not be greater than higher mailbox number");
126  "Highest mailbox number must not be larger than total number of mailboxes");
127 
128 /*========== Static Constant and Variable Definitions =======================*/
129 
130 /** tracks the local state of the can module */
132  .periodicEnable = false,
133  .currentSensorPresent = {GEN_REPEAT_U(false, GEN_STRIP(BS_NR_OF_STRINGS))},
134  .currentSensorCCPresent = {GEN_REPEAT_U(false, GEN_STRIP(BS_NR_OF_STRINGS))},
135  .currentSensorECPresent = {GEN_REPEAT_U(false, GEN_STRIP(BS_NR_OF_STRINGS))},
136 };
137 
138 /*========== Extern Constant and Variable Definitions =======================*/
139 
140 /*========== Static Function Prototypes =====================================*/
141 
142 /**
143  * @brief Called in case of CAN TX interrupt.
144  * @param pNode CAN interface on which message was sent
145  * @param messageBox message box on which message was sent
146  */
147 static void CAN_TxInterrupt(canBASE_t *pNode, uint32 messageBox);
148 
149 /**
150  * @brief Called in case of CAN RX interrupt.
151  * @param pNode CAN interface on which message was received
152  * @param messageBox message box on which message was received
153  */
154 static void CAN_RxInterrupt(canBASE_t *pNode, uint32 messageBox);
155 
156 /**
157  * @brief Handles the processing of messages that are meant to be
158  * transmitted.
159  * @details This function looks for the repetition times and the repetition
160  * phase of messages that are intended to be sent periodically.
161  * If a comparison with an internal counter (i.e., the counter how
162  * often this function has been called) states that a transmit is
163  * pending, the message is composed by call of CANS_ComposeMessage
164  * and transferred to the buffer of the CAN module.
165  * If a callback function is declared in configuration, this callback
166  * is called after successful transmission.
167  * @return #STD_OK if a CAN transfer was made, #STD_NOT_OK otherwise
168  */
170 
171 /**
172  * @brief Checks if the CAN messages come in the specified time window
173  * @details The time delta where a message is expected to be received needs to
174  * be between the configured limits #CAN_TIMING_LOWER_LIMIT_COUNTS and
175  * #CAN_TIMING_UPPER_LIMIT_COUNTS,
176  * If the message is received within the time frame the check is true,
177  * false otherwise.
178  * The result is then reported via flags in the DIAG module.
179  */
180 static void CAN_CheckCanTiming(void);
181 
182 #if BS_CURRENT_SENSOR_PRESENT == true
183 /**
184  * @brief Sets flag to indicate current sensor is present.
185  * @param command true if current sensor present, otherwise false
186  * @param stringNumber string addressed
187  */
188 static void CAN_SetCurrentSensorPresent(bool command, uint8_t stringNumber);
189 
190 /**
191  * @brief Sets flag to indicate current sensor sends C-C values.
192  * @param command true if coulomb counting message detected,
193  * otherwise false
194  * @param stringNumber string addressed
195  */
196 static void CAN_SetCurrentSensorCcPresent(bool command, uint8_t stringNumber);
197 
198 /**
199  * @brief Sets flag to indicate current sensor sends C-C values.
200  * @param command true if energy counting message detected, otherwise
201  * false
202  * @param stringNumber string addressed
203  */
204 static void CAN_SetCurrentSensorEcPresent(bool command, uint8_t stringNumber);
205 
206 static void CAN_CheckCanTimingOfCurrentSensor(void);
207 #endif /* BS_CURRENT_SENSOR_PRESENT == true */
208 
209 /**
210  * @brief Initialize RX mailboxes for usage with extended identifiers
211  * @details The first 32 mailboxes are configured via HALCoGen as RX mailboxes
212  * to be used with standard 11-bit identifiers. As the configuration
213  * if standard or extended identifiers should be used can only be
214  * configured for all mailboxes and not individually for each mailbox
215  * this configuration is done here.
216  *
217  * The HALCoGen configuration for the mailboxes 61-64 is overwritten
218  * here and they are configured to received all CAN messages with an
219  * extended identifier.
220  *
221  * This configuration is only done for CAN nodes canReg1 and canReg2!
222  */
224 
225 /** initialize the SPI interface to the CAN transceiver */
226 static void CAN_InitializeTransceiver(void);
227 
228 /** checks that the configured message period for Tx messages is valid */
229 static void CAN_ValidateConfiguredTxMessagePeriod(void);
230 
231 /**
232  * @brief get pointer CAN node configuration struct from register address
233  * @param pNodeRegister pointer to CAN node hardware register address
234  * @return pointer to node configuration struct
235  */
236 static CAN_NODE_s *CAN_GetNodeConfigurationStructFromRegisterAddress(canBASE_t *pNodeRegister);
237 
238 /*========== Static Function Implementations ================================*/
239 
241  /* Content copied from HALCoGen generated configuration file HL_can.c
242  * Date: 11-Dec-2018
243  * Version: 04.07.01
244  */
245 
246  /* AXIVION Disable Style Generic-NoMagicNumbers: Content copied from HALCoGen generated configuration file */
247  /* AXIVION Disable Style MisraC2012-2.2: Content copied from HALCoGen generated configuration file */
248  /* AXIVION Disable Style IISB-LiteralSuffixesCheck: Content copied from HALCoGen generated configuration file */
249  /* AXIVION Disable Style Generic-NoEmptyLoops: Content copied from HALCoGen generated configuration file */
250 
251  /* Reconfigure CAN1 mailboxes 42, 61, 62, 63 and 64 */
252 
253  /** - Setup control register
254  * - Disable automatic wakeup on bus activity
255  * - Local power down mode disabled
256  * - Disable DMA request lines
257  * - Enable global Interrupt Line 0 and 1
258  * - Disable debug mode
259  * - Release from software reset
260  * - Enable/Disable parity or ECC
261  * - Enable/Disable auto bus on timer
262  * - Setup message completion before entering debug state
263  * - Setup normal operation mode
264  * - Request write access to the configuration registers
265  * - Setup automatic retransmission of messages
266  * - Disable error interrupts
267  * - Disable status interrupts
268  * - Enter initialization mode
269  */
270  canREG1->CTL = (uint32)0x00000000U | (uint32)0x00000000U | (uint32)((uint32)0x0000000AU << 10U) |
271  (uint32)0x00020043U;
272 
273  /** - Clear all pending error flags and reset current status */
274  canREG1->ES |= 0xFFFFFFFFU;
275 
276  /** - Setup auto bus on timer period */
277  canREG1->ABOTR = (uint32)0U;
278 
279  /** - Initialize message 42
280  * - Wait until IF1 is ready for use
281  * - Set message mask
282  * - Set message control word
283  * - Set message arbitration
284  * - Set IF1 control byte
285  * - Set IF1 message number
286  */
287  /* SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found -
288  * Hardware Status check for execution sequence" */
289  while ((canREG1->IF1STAT & 0x80U) == 0x80U) {
290  } /* Wait */
291 
292  canREG1->IF1MSK = 0xC0000000U | (uint32)((uint32)((uint32)0x00000000U & (uint32)0x000007FFU) << (uint32)18U);
293  canREG1->IF1ARB = (uint32)0x80000000U | (uint32)0x00000000U | (uint32)0x00000000U |
294  (uint32)((uint32)((uint32)0U & (uint32)0x000007FFU) << (uint32)18U);
295  canREG1->IF1MCTL = 0x00001000U | (uint32)0x00000400U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)8U;
296  canREG1->IF1CMD = (uint8)0xF8U;
297  canREG1->IF1NO = 42U;
298 
299  /** - Initialize message 61
300  * - Wait until IF1 is ready for use
301  * - Set message mask
302  * - Set message control word
303  * - Set message arbitration
304  * - Set IF1 control byte
305  * - Set IF1 message number
306  */
307  /* SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found -
308  * Hardware Status check for execution sequence" */
309  while ((canREG1->IF1STAT & 0x80U) == 0x80U) {
310  } /* Wait */
311 
312  canREG1->IF1MSK = 0xC0000000U | (uint32)((uint32)((uint32)0x00000000U & (uint32)0x1FFFFFFFU) << (uint32)0U);
313  canREG1->IF1ARB = (uint32)0x80000000U | (uint32)0x40000000U | (uint32)0x00000000U |
314  (uint32)((uint32)((uint32)0U & (uint32)0x1FFFFFFFU) << (uint32)0U);
315  canREG1->IF1MCTL = 0x00001000U | (uint32)0x00000400U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)8U;
316  canREG1->IF1CMD = (uint8)0xF8U;
317  canREG1->IF1NO = 61U;
318 
319  /** - Initialize message 62
320  * - Wait until IF2 is ready for use
321  * - Set message mask
322  * - Set message control word
323  * - Set message arbitration
324  * - Set IF2 control byte
325  * - Set IF2 message number
326  */
327  /* SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found -
328  * Hardware Status check for execution sequence" */
329  while ((canREG1->IF2STAT & 0x80U) == 0x80U) {
330  } /* Wait */
331 
332  canREG1->IF2MSK = 0xC0000000U | (uint32)((uint32)((uint32)0x00000000U & (uint32)0x1FFFFFFFU) << (uint32)0U);
333  canREG1->IF2ARB = (uint32)0x80000000U | (uint32)0x40000000U | (uint32)0x00000000U |
334  (uint32)((uint32)((uint32)0U & (uint32)0x1FFFFFFFU) << (uint32)0U);
335  canREG1->IF2MCTL = 0x00001000U | (uint32)0x00000400U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)8U;
336  canREG1->IF2CMD = (uint8)0xF8U;
337  canREG1->IF2NO = 62U;
338 
339  /** - Initialize message 63
340  * - Wait until IF1 is ready for use
341  * - Set message mask
342  * - Set message control word
343  * - Set message arbitration
344  * - Set IF1 control byte
345  * - Set IF1 message number
346  */
347  /* SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found -
348  * Hardware Status check for execution sequence" */
349  while ((canREG1->IF1STAT & 0x80U) == 0x80U) {
350  } /* Wait */
351 
352  canREG1->IF1MSK = 0xC0000000U | (uint32)((uint32)((uint32)0x00000000U & (uint32)0x1FFFFFFFU) << (uint32)0U);
353  canREG1->IF1ARB = (uint32)0x80000000U | (uint32)0x40000000U | (uint32)0x00000000U |
354  (uint32)((uint32)((uint32)0U & (uint32)0x1FFFFFFFU) << (uint32)0U);
355  canREG1->IF1MCTL = 0x00001000U | (uint32)0x00000400U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)8U;
356  canREG1->IF1CMD = (uint8)0xF8U;
357  canREG1->IF1NO = 63U;
358 
359  /** - Initialize message 64
360  * - Wait until IF2 is ready for use
361  * - Set message mask
362  * - Set message control word
363  * - Set message arbitration
364  * - Set IF2 control byte
365  * - Set IF2 message number
366  */
367  /* SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found -
368  * Hardware Status check for execution sequence" */
369  while ((canREG1->IF2STAT & 0x80U) == 0x80U) {
370  } /* Wait */
371 
372  canREG1->IF2MSK = 0xC0000000U | (uint32)((uint32)((uint32)0x00000000U & (uint32)0x1FFFFFFFU) << (uint32)0U);
373  canREG1->IF2ARB = (uint32)0x80000000U | (uint32)0x40000000U | (uint32)0x00000000U |
374  (uint32)((uint32)((uint32)0U & (uint32)0x1FFFFFFFU) << (uint32)0U);
375  canREG1->IF2MCTL = 0x00001000U | (uint32)0x00000400U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)8U;
376  canREG1->IF2CMD = (uint8)0xF8U;
377  canREG1->IF2NO = 64U;
378 
379  /** - Setup IF1 for data transmission
380  * - Wait until IF1 is ready for use
381  * - Set IF1 control byte
382  */
383  /* SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found -
384  * Hardware Status check for execution sequence" */
385  while ((canREG1->IF1STAT & 0x80U) == 0x80U) {
386  } /* Wait */
387  canREG1->IF1CMD = 0x87U;
388 
389  /** - Setup IF2 for reading data
390  * - Wait until IF1 is ready for use
391  * - Set IF1 control byte
392  */
393  /* SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found -
394  * Hardware Status check for execution sequence" */
395  while ((canREG1->IF2STAT & 0x80U) == 0x80U) {
396  } /* Wait */
397  canREG1->IF2CMD = 0x17U;
398 
399  /** - Leave configuration and initialization mode */
400  canREG1->CTL &= ~(uint32)(0x00000041U);
401 
402  /** Reconfigure CAN2 mailboxes 61 - 64 */
403 
404  /** - Setup control register
405  * - Disable automatic wakeup on bus activity
406  * - Local power down mode disabled
407  * - Disable DMA request lines
408  * - Enable global Interrupt Line 0 and 1
409  * - Disable debug mode
410  * - Release from software reset
411  * - Enable/Disable parity or ECC
412  * - Enable/Disable auto bus on timer
413  * - Setup message completion before entering debug state
414  * - Setup normal operation mode
415  * - Request write access to the configuration registers
416  * - Setup automatic retransmission of messages
417  * - Disable error interrupts
418  * - Disable status interrupts
419  * - Enter initialization mode
420  */
421  canREG2->CTL = (uint32)0x00000000U | (uint32)0x00000000U | (uint32)((uint32)0x0000000AU << 10U) | 0x00020043U;
422 
423  /** - Clear all pending error flags and reset current status */
424  canREG2->ES |= 0xFFFFFFFFU;
425 
426  /** - Initialize message 61
427  * - Wait until IF1 is ready for use
428  * - Set message mask
429  * - Set message control word
430  * - Set message arbitration
431  * - Set IF1 control byte
432  * - Set IF1 message number
433  */
434  /* SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found -
435  * Hardware Status check for execution sequence" */
436  while ((canREG2->IF1STAT & 0x80U) == 0x80U) {
437  } /* Wait */
438 
439  canREG2->IF1MSK = 0xC0000000U | (uint32)((uint32)((uint32)0x00000000U & (uint32)0x1FFFFFFFU) << (uint32)0U);
440  canREG2->IF1ARB = (uint32)0x80000000U | (uint32)0x40000000U | (uint32)0x00000000U |
441  (uint32)((uint32)((uint32)0U & (uint32)0x1FFFFFFFU) << (uint32)0U);
442  canREG2->IF1MCTL = 0x00001000U | (uint32)0x00000400U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)8U;
443  canREG2->IF1CMD = (uint8)0xF8U;
444  canREG2->IF1NO = 61U;
445 
446  /** - Initialize message 62
447  * - Wait until IF2 is ready for use
448  * - Set message mask
449  * - Set message control word
450  * - Set message arbitration
451  * - Set IF2 control byte
452  * - Set IF2 message number
453  */
454  /* SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found -
455  * Hardware Status check for execution sequence" */
456  while ((canREG2->IF2STAT & 0x80U) == 0x80U) {
457  } /* Wait */
458 
459  canREG2->IF2MSK = 0xC0000000U | (uint32)((uint32)((uint32)0x00000000U & (uint32)0x1FFFFFFFU) << (uint32)0U);
460  canREG2->IF2ARB = (uint32)0x80000000U | (uint32)0x40000000U | (uint32)0x00000000U |
461  (uint32)((uint32)((uint32)0U & (uint32)0x1FFFFFFFU) << (uint32)0U);
462  canREG2->IF2MCTL = 0x00001000U | (uint32)0x00000400U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)8U;
463  canREG2->IF2CMD = (uint8)0xF8U;
464  canREG2->IF2NO = 62U;
465 
466  /** - Initialize message 63
467  * - Wait until IF1 is ready for use
468  * - Set message mask
469  * - Set message control word
470  * - Set message arbitration
471  * - Set IF1 control byte
472  * - Set IF1 message number
473  */
474  /* SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found -
475  * Hardware Status check for execution sequence" */
476  while ((canREG2->IF1STAT & 0x80U) == 0x80U) {
477  } /* Wait */
478 
479  canREG2->IF1MSK = 0xC0000000U | (uint32)((uint32)((uint32)0x00000000U & (uint32)0x1FFFFFFFU) << (uint32)0U);
480  canREG2->IF1ARB = (uint32)0x80000000U | (uint32)0x40000000U | (uint32)0x00000000U |
481  (uint32)((uint32)((uint32)0U & (uint32)0x1FFFFFFFU) << (uint32)0U);
482  canREG2->IF1MCTL = 0x00001000U | (uint32)0x00000400U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)8U;
483  canREG2->IF1CMD = (uint8)0xF8U;
484  canREG2->IF1NO = 63U;
485 
486  /** - Initialize message 64
487  * - Wait until IF2 is ready for use
488  * - Set message mask
489  * - Set message control word
490  * - Set message arbitration
491  * - Set IF2 control byte
492  * - Set IF2 message number
493  */
494  /* SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found -
495  * Hardware Status check for execution sequence" */
496  while ((canREG2->IF2STAT & 0x80U) == 0x80U) {
497  } /* Wait */
498 
499  canREG2->IF2MSK = 0xC0000000U | (uint32)((uint32)((uint32)0x00000000U & (uint32)0x1FFFFFFFU) << (uint32)0U);
500  canREG2->IF2ARB = (uint32)0x80000000U | (uint32)0x40000000U | (uint32)0x00000000U |
501  (uint32)((uint32)((uint32)0U & (uint32)0x1FFFFFFFU) << (uint32)0U);
502  canREG2->IF2MCTL = 0x00001000U | (uint32)0x00000400U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)8U;
503  canREG2->IF2CMD = (uint8)0xF8U;
504  canREG2->IF2NO = 64U;
505 
506  /** - Setup IF1 for data transmission
507  * - Wait until IF1 is ready for use
508  * - Set IF1 control byte
509  */
510  /* SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found -
511  * Hardware Status check for execution sequence" */
512  while ((canREG2->IF1STAT & 0x80U) == 0x80U) {
513  } /* Wait */
514  canREG2->IF1CMD = 0x87U;
515 
516  /** - Setup IF2 for reading data
517  * - Wait until IF1 is ready for use
518  * - Set IF1 control byte
519  */
520  /* SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found -
521  * Hardware Status check for execution sequence" */
522  while ((canREG2->IF2STAT & 0x80U) == 0x80U) {
523  } /* Wait */
524  canREG2->IF2CMD = 0x17U;
525 
526  /** - Leave configuration and initialization mode */
527  canREG2->CTL &= ~(uint32)(0x00000041U);
528 
529  /* AXIVION Enable Style Generic-NoMagicNumbers: */
530  /* AXIVION Enable Style MisraC2012-2.2: */
531  /* AXIVION Enable Style IISB-LiteralSuffixesCheck: */
532  /* AXIVION Enable Style Generic-NoEmptyLoops: */
533 }
534 
535 static void CAN_InitializeTransceiver(void) {
536  /** Initialize transceiver for CAN1 */
541 
542  /** Initialize transceiver for CAN2 */
547 }
548 
550  for (uint16_t i = 0u; i < can_txLength; i++) {
551  if (can_txMessages[i].timing.period == 0u) {
553  }
554  }
555 }
556 
558  FAS_ASSERT(pNodeRegister != NULL_PTR);
559  CAN_NODE_s *node = NULL_PTR;
560  /* Find correct CAN node configuration struct */
561  if (pNodeRegister == can_node1.canNodeRegister) {
562  node = (CAN_NODE_s *)&can_node1;
563  } else if (pNodeRegister == can_node2Isolated.canNodeRegister) {
564  node = (CAN_NODE_s *)&can_node2Isolated;
565  } else {
566  /* Invalid address. This should not have happened */
568  }
569  return node;
570 }
571 
572 static void CAN_RxInterrupt(canBASE_t *pNode, uint32 messageBox) {
573  FAS_ASSERT(pNode != NULL_PTR);
574  FAS_ASSERT(messageBox <= CAN_TOTAL_NUMBER_OF_MESSAGE_BOXES); /* hardware starts counting at 1 -> use <= */
575 
576  uint8_t messageData[CAN_DEFAULT_DLC] = {0u};
577  /**
578  * Read even if queues are not created, otherwise message boxes get full.
579  * Possible return values:
580  * - 0: no new data
581  * - 1: no data lost
582  * - 3: data lost */
583  uint32_t retval = canGetData(pNode, messageBox, (uint8 *)&messageData[0]); /* copy to RAM */
584 
585  /* Check that CAN RX queue is started before using it and data is valid */
586  if ((ftsk_allQueuesCreated == true) && (retval == CAN_HAL_RETVAL_NO_DATA_LOST)) {
587  CAN_BUFFER_ELEMENT_s can_rxBuffer = {NULL_PTR, 0u, CAN_INVALID_TYPE, {0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u}};
588  /* Find configured CAN node from register address */
590 
591  /* Check message box number if it is a mailbox reserved for extended identifiers or not */
592  if (!((messageBox >= CAN_LOWEST_MAILBOX_FOR_EXTENDED_IDENTIFIERS) &&
594  /* Extract standard identifier from IF2ARB register*/
595  can_rxBuffer.id = canGetID(pNode, messageBox) >> CAN_IF2ARB_STANDARD_IDENTIFIER_SHIFT;
596  can_rxBuffer.idType = CAN_STANDARD_IDENTIFIER_11_BIT;
597  } else {
598  /* Extract extended identifier from IF2ARB register*/
599  can_rxBuffer.id = canGetID(pNode, messageBox) >> CAN_IF2ARB_EXTENDED_IDENTIFIER_SHIFT;
600  can_rxBuffer.idType = CAN_EXTENDED_IDENTIFIER_29_BIT;
601  }
602 
603  /* Write data into buffer */
604  can_rxBuffer.data[CAN_BYTE_0_POSITION] = messageData[CAN_BYTE_0_POSITION];
605  can_rxBuffer.data[CAN_BYTE_1_POSITION] = messageData[CAN_BYTE_1_POSITION];
606  can_rxBuffer.data[CAN_BYTE_2_POSITION] = messageData[CAN_BYTE_2_POSITION];
607  can_rxBuffer.data[CAN_BYTE_3_POSITION] = messageData[CAN_BYTE_3_POSITION];
608  can_rxBuffer.data[CAN_BYTE_4_POSITION] = messageData[CAN_BYTE_4_POSITION];
609  can_rxBuffer.data[CAN_BYTE_5_POSITION] = messageData[CAN_BYTE_5_POSITION];
610  can_rxBuffer.data[CAN_BYTE_6_POSITION] = messageData[CAN_BYTE_6_POSITION];
611  can_rxBuffer.data[CAN_BYTE_7_POSITION] = messageData[CAN_BYTE_7_POSITION];
612 
613  if (OS_SendToBackOfQueueFromIsr(ftsk_canRxQueue, (void *)&can_rxBuffer, NULL_PTR) == OS_SUCCESS) {
614  /* queue is not full */
616  } else {
617  /* queue is full */
619  }
620  }
621 }
622 
624  STD_RETURN_TYPE_e retVal = STD_NOT_OK;
625  static uint32_t counterTicks = 0;
626  uint8_t data[CAN_MAX_DLC] = {0};
627 
628  for (uint16_t i = 0u; i < can_txLength; i++) {
629  if (((counterTicks * CAN_TICK_ms) % (can_txMessages[i].timing.period)) == can_txMessages[i].timing.phase) {
630  if (can_txMessages[i].callbackFunction != NULL_PTR) {
632  can_txMessages[i].message, data, can_txMessages[i].pMuxId, &can_kShim);
633  /* CAN messages are currently discarded if all message boxes
634  * are full. They will not be retransmitted within the next
635  * call of CAN_PeriodicTransmit() */
636  CAN_DataSend(
637  can_txMessages[i].canNode, can_txMessages[i].message.id, can_txMessages[i].message.idType, data);
638  retVal = STD_OK;
639  }
640  }
641  }
642 
643  counterTicks++;
644  return retVal;
645 }
646 
647 static void CAN_CheckCanTiming(void) {
648  uint32_t currentTime;
651 
652  currentTime = OS_GetTickCount();
653  DATA_READ_DATA(&stateRequestTab, &errorFlagsTab);
654 
655  /* Is the BMS still getting CAN messages? */
656  if ((currentTime - stateRequestTab.header.timestamp) <= CAN_TIMING_UPPER_LIMIT_COUNTS) {
657  if (((stateRequestTab.header.timestamp - stateRequestTab.header.previousTimestamp) >=
659  ((stateRequestTab.header.timestamp - stateRequestTab.header.previousTimestamp) <=
662  } else {
664  }
665  } else {
667  }
668 
669 #if BS_CURRENT_SENSOR_PRESENT == true
671 #endif /* BS_CURRENT_SENSOR_PRESENT == true */
672 }
673 
674 #if BS_CURRENT_SENSOR_PRESENT == true
676  uint32_t currentTime = OS_GetTickCount();
678  /* check time stamps of current measurements */
679  DATA_READ_DATA(&currentTab);
680 
681  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
682  /* Current has been measured at least once */
683  if (currentTab.timestampCurrent[s] != 0u) {
684  /* Check time since last received string current data */
685  if ((currentTime - currentTab.timestampCurrent[s]) > BS_CURRENT_MEASUREMENT_RESPONSE_TIMEOUT_ms) {
687  } else {
689  if (can_state.currentSensorPresent[s] == false) {
691  }
692  }
693  }
694 
695  /* check time stamps of CC measurements */
696  /* if timestamp_cc != 0, this means current sensor cc message has been received at least once */
697  if (currentTab.timestampCurrentCounting[s] != 0) {
698  if ((currentTime - currentTab.timestampCurrentCounting[s]) >
701  } else {
703  if (can_state.currentSensorCCPresent[s] == false) {
705  }
706  }
707  }
708 
709  /* check time stamps of EC measurements */
710  /* if timestamp_ec != 0, this means current sensor ec message has been received at least once */
711  if (currentTab.timestampEnergyCounting[s] != 0) {
712  if ((currentTime - currentTab.timestampEnergyCounting[s]) >
715  } else {
717  if (can_state.currentSensorECPresent[s] == false) {
719  }
720  }
721  }
722  }
723 }
724 
725 static void CAN_SetCurrentSensorPresent(bool command, uint8_t stringNumber) {
726  if (command == true) {
728  can_state.currentSensorPresent[stringNumber] = true;
730  } else {
732  can_state.currentSensorPresent[stringNumber] = false;
734  }
735 }
736 
737 static void CAN_SetCurrentSensorCcPresent(bool command, uint8_t stringNumber) {
738  if (command == true) {
740  can_state.currentSensorCCPresent[stringNumber] = true;
742  } else {
744  can_state.currentSensorCCPresent[stringNumber] = false;
746  }
747 }
748 
749 static void CAN_SetCurrentSensorEcPresent(bool command, uint8_t stringNumber) {
750  if (command == true) {
752  can_state.currentSensorECPresent[stringNumber] = true;
754  } else {
756  can_state.currentSensorECPresent[stringNumber] = false;
758  }
759 }
760 #endif /* BS_CURRENT_SENSOR_PRESENT == true */
761 
762 static void CAN_TxInterrupt(canBASE_t *pNode, uint32 messageBox) {
763  /* AXIVION Routine Generic-MissingParameterAssert: pNode: unused parameter */
764  /* AXIVION Routine Generic-MissingParameterAssert: messageBox: unused parameter */
765  (void)pNode;
766  (void)messageBox;
767 }
768 
769 /*========== Extern Function Implementations ================================*/
770 
771 extern void CAN_Initialize(void) {
772  canInit();
773  /* This function overwrites HALCoGen configuration mailbox configuration 61 - 64 for CAN1 and CAN2. */
775  /* PEX pins are used for transceiver configuration -> I2C and port expander
776  * needs to be initialized previously for a successful initialization. */
779 }
780 
781 extern STD_RETURN_TYPE_e CAN_DataSend(CAN_NODE_s *pNode, uint32_t id, CAN_IDENTIFIER_TYPE_e idType, uint8 *pData) {
782  FAS_ASSERT(pNode != NULL_PTR);
783  /* AXIVION Routine Generic-MissingParameterAssert: id: parameter accepts whole range */
785  FAS_ASSERT(pData != NULL_PTR);
786  FAS_ASSERT((pNode == CAN_NODE_1) || (pNode == CAN_NODE_2));
787 
788  STD_RETURN_TYPE_e result = STD_NOT_OK;
789 
790  /**
791  * Parse all TX message boxes until we find a free one,
792  * then use it to send the CAN message.
793  * In the HAL, message box numbers start from 1, not 0.
794  */
795  for (uint8_t messageBox = 1u; messageBox <= CAN_NR_OF_TX_MESSAGE_BOX; messageBox++) {
796  if (canIsTxMessagePending(pNode->canNodeRegister, messageBox) == 0u) {
797  /* id shifted by 18 to use standard frame */
798  /* standard frame: bits [28:18] */
799  /* extended frame: bits [28:0] */
800  /* bit 29 set to 1: to set direction Tx in IF2ARB register */
801  /* bit 30 set to 1: 29-bit ("extended") identifier is used for this message object */
802  if (idType == CAN_STANDARD_IDENTIFIER_11_BIT) {
803  canUpdateID(
804  pNode->canNodeRegister,
805  messageBox,
808  } else {
809  /* Extended 29-bit identifier is used for this node */
810  canUpdateID(
811  pNode->canNodeRegister,
812  messageBox,
815  }
816  canTransmit(pNode->canNodeRegister, messageBox, pData);
817  result = STD_OK;
818  break;
819  }
820  }
821  return result;
822 }
823 
824 extern void CAN_MainFunction(void) {
826  if (can_state.periodicEnable == true) {
828  }
829 }
830 
831 extern void CAN_ReadRxBuffer(void) {
832  if (ftsk_allQueuesCreated == true) {
833  CAN_BUFFER_ELEMENT_s can_rxBuffer = {NULL_PTR, 0u, CAN_INVALID_TYPE, {0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u}};
834  while (OS_ReceiveFromQueue(ftsk_canRxQueue, (void *)&can_rxBuffer, 0u) == OS_SUCCESS) {
835  /* data queue was not empty */
836  for (uint16_t i = 0u; i < can_rxLength; i++) {
837  if ((can_rxBuffer.canNode == can_rxMessages[i].canNode) &&
838  (can_rxBuffer.id == can_rxMessages[i].message.id) &&
839  (can_rxBuffer.idType == can_rxMessages[i].message.idType)) {
840  if (can_rxMessages[i].callbackFunction != NULL_PTR) {
841  can_rxMessages[i].callbackFunction(can_rxMessages[i].message, can_rxBuffer.data, &can_kShim);
842  }
843  }
844  }
845  }
846  }
847 }
848 
849 extern void CAN_EnablePeriodic(bool command) {
850  if (command == true) {
851  can_state.periodicEnable = true;
852  } else {
853  can_state.periodicEnable = false;
854  }
855 }
856 
857 extern bool CAN_IsCurrentSensorPresent(uint8_t stringNumber) {
858  FAS_ASSERT(stringNumber < BS_NR_OF_STRINGS);
859  return can_state.currentSensorPresent[stringNumber];
860 }
861 
862 extern bool CAN_IsCurrentSensorCcPresent(uint8_t stringNumber) {
863  FAS_ASSERT(stringNumber < BS_NR_OF_STRINGS);
864  return can_state.currentSensorCCPresent[stringNumber];
865 }
866 
867 extern bool CAN_IsCurrentSensorEcPresent(uint8_t stringNumber) {
868  FAS_ASSERT(stringNumber < BS_NR_OF_STRINGS);
869  return can_state.currentSensorECPresent[stringNumber];
870 }
871 
872 /** called in case of CAN interrupt, defined as weak in HAL */
873 /* 'extern' is omitted here (as opposed to how the foxBMS project declares
874  and defines functions) as the TI HAL convention does omit the keyword here
875  and we want to stay consistent with TI's declaration.) */
876 /* AXIVION Next Codeline Style Linker-Multiple_Definition: TI HAL only provides a weak implementation */
877 void UNIT_TEST_WEAK_IMPL canMessageNotification(canBASE_t *node, uint32 messageBox) {
878  /* AXIVION Routine Generic-MissingParameterAssert: node: unchecked in interrupt */
879  /* AXIVION Routine Generic-MissingParameterAssert: messageBox: unchecked in interrupt */
880 
881  if (messageBox <= CAN_NR_OF_TX_MESSAGE_BOX) {
882  CAN_TxInterrupt(node, messageBox);
883  } else {
884  CAN_RxInterrupt(node, messageBox);
885  }
886 }
887 
888 /*========== Externalized Static Function Implementations (Unit Test) =======*/
889 #ifdef UNITY_UNIT_TEST
891  return &can_state;
892 }
893 #endif
#define BS_ENERGY_COUNTING_MEASUREMENT_RESPONSE_TIMEOUT_ms
#define BS_NR_OF_STRINGS
Number of parallel strings in the battery pack.
#define BS_COULOMB_COUNTING_MEASUREMENT_RESPONSE_TIMEOUT_ms
#define BS_CURRENT_MEASUREMENT_RESPONSE_TIMEOUT_ms
#define CAN_IF2ARB_EXTENDED_IDENTIFIER_SHIFT
Definition: can.c:94
static CAN_NODE_s * CAN_GetNodeConfigurationStructFromRegisterAddress(canBASE_t *pNodeRegister)
get pointer CAN node configuration struct from register address
Definition: can.c:557
static void CAN_RxInterrupt(canBASE_t *pNode, uint32 messageBox)
Called in case of CAN RX interrupt.
Definition: can.c:572
bool CAN_IsCurrentSensorCcPresent(uint8_t stringNumber)
get flag if CC message from current sensor is received.
Definition: can.c:862
void CAN_MainFunction(void)
Calls the functions to drive the CAN interface. Makes the CAN timing checks and sends the periodic me...
Definition: can.c:824
static void CAN_ValidateConfiguredTxMessagePeriod(void)
Definition: can.c:549
static void CAN_SetCurrentSensorCcPresent(bool command, uint8_t stringNumber)
Sets flag to indicate current sensor sends C-C values.
Definition: can.c:737
static STD_RETURN_TYPE_e CAN_PeriodicTransmit(void)
Handles the processing of messages that are meant to be transmitted.
Definition: can.c:623
#define CAN_IF2ARB_USE_EXTENDED_IDENTIFIER
Definition: can.c:113
#define CAN_IF2ARB_SET_TX_DIRECTION
Definition: can.c:105
CAN_STATE_s * TEST_CAN_GetCANState(void)
Definition: can.c:890
#define CAN_HAL_RETVAL_NO_DATA_LOST
Definition: can.c:82
static void CAN_CheckCanTiming(void)
Checks if the CAN messages come in the specified time window.
Definition: can.c:647
#define CAN_IF2ARB_STANDARD_IDENTIFIER_SHIFT
Definition: can.c:92
#define CAN_TIMING_LOWER_LIMIT_COUNTS
Definition: can.c:76
static void CAN_InitializeTransceiver(void)
Definition: can.c:535
void UNIT_TEST_WEAK_IMPL canMessageNotification(canBASE_t *node, uint32 messageBox)
Definition: can.c:877
bool CAN_IsCurrentSensorEcPresent(uint8_t stringNumber)
get flag if EC message from current sensor is received
Definition: can.c:867
#define CAN_HIGHEST_MAILBOX_FOR_EXTENDED_IDENTIFIERS
Definition: can.c:118
static void CAN_TxInterrupt(canBASE_t *pNode, uint32 messageBox)
Called in case of CAN TX interrupt.
Definition: can.c:762
void CAN_ReadRxBuffer(void)
Checks the data received per CAN. A receive buffer is used because CAN frames are received in an inte...
Definition: can.c:831
bool CAN_IsCurrentSensorPresent(uint8_t stringNumber)
set flag for presence of current sensor.
Definition: can.c:857
static void CAN_SetCurrentSensorEcPresent(bool command, uint8_t stringNumber)
Sets flag to indicate current sensor sends C-C values.
Definition: can.c:749
#define CAN_TIMING_UPPER_LIMIT_COUNTS
Definition: can.c:79
STD_RETURN_TYPE_e CAN_DataSend(CAN_NODE_s *pNode, uint32_t id, CAN_IDENTIFIER_TYPE_e idType, uint8 *pData)
Sends over CAN the data passed in parameters. This function goes over the message boxes and marks the...
Definition: can.c:781
static void CAN_CheckCanTimingOfCurrentSensor(void)
Definition: can.c:675
#define CAN_IF2ARB_USE_STANDARD_IDENTIFIER
Definition: can.c:111
static void CAN_ConfigureRxMailboxesForExtendedIdentifiers(void)
Initialize RX mailboxes for usage with extended identifiers.
Definition: can.c:240
#define CAN_LOWEST_MAILBOX_FOR_EXTENDED_IDENTIFIERS
Definition: can.c:117
static void CAN_SetCurrentSensorPresent(bool command, uint8_t stringNumber)
Sets flag to indicate current sensor is present.
Definition: can.c:725
void CAN_Initialize(void)
Enables the CAN transceiver.. This function sets th pins to enable the CAN transceiver....
Definition: can.c:771
static CAN_STATE_s can_state
Definition: can.c:131
FAS_STATIC_ASSERT((CAN_LOWEST_MAILBOX_FOR_EXTENDED_IDENTIFIERS<=CAN_HIGHEST_MAILBOX_FOR_EXTENDED_IDENTIFIERS), "Lower mailbox number must not be greater than higher mailbox number")
void CAN_EnablePeriodic(bool command)
Enables periodic sending per CAN. This is used to prevent sending uninitialized data per CAN (e....
Definition: can.c:849
Header for the driver for the CAN module.
#define CAN_NR_OF_TX_MESSAGE_BOX
Definition: can.h:74
#define CAN_TOTAL_NUMBER_OF_MESSAGE_BOXES
Definition: can.h:69
#define CAN_TICK_ms
Definition: can.h:79
const CAN_SHIM_s can_kShim
Definition: can_cfg.c:101
const CAN_NODE_s can_node1
Definition: can_cfg.c:74
const CAN_NODE_s can_node2Isolated
Definition: can_cfg.c:78
const CAN_RX_MESSAGE_TYPE_s can_rxMessages[]
Definition: can_cfg_rx.c:76
#define CAN2_ENABLE_PIN
Definition: can_cfg.h:94
#define CAN1_STANDBY_PIN
Definition: can_cfg.h:93
#define CAN_NODE_2
Definition: can_cfg.h:81
#define CAN1_ENABLE_PIN
Definition: can_cfg.h:92
const uint8_t can_txLength
Definition: can_cfg_tx.c:103
#define CAN2_STANDBY_PIN
Definition: can_cfg.h:95
#define CAN_NODE_1
Definition: can_cfg.h:80
const CAN_TX_MESSAGE_TYPE_s can_txMessages[]
Definition: can_cfg_tx.c:86
const uint8_t can_rxLength
Definition: can_cfg_rx.c:92
#define CAN_DEFAULT_DLC
Definition: can_cfg.h:103
#define CAN_MAX_DLC
Definition: can_cfg.h:101
CAN_IDENTIFIER_TYPE_e
Definition: can_cfg.h:162
@ CAN_EXTENDED_IDENTIFIER_29_BIT
Definition: can_cfg.h:164
@ CAN_INVALID_TYPE
Definition: can_cfg.h:165
@ CAN_STANDARD_IDENTIFIER_11_BIT
Definition: can_cfg.h:163
Headers for the helper functions for the CAN module.
#define CAN_BYTE_2_POSITION
Definition: can_helper.h:73
#define CAN_BYTE_4_POSITION
Definition: can_helper.h:75
#define CAN_BYTE_0_POSITION
Definition: can_helper.h:71
#define CAN_BYTE_6_POSITION
Definition: can_helper.h:77
#define CAN_BYTE_7_POSITION
Definition: can_helper.h:78
#define CAN_BYTE_3_POSITION
Definition: can_helper.h:74
#define CAN_BYTE_5_POSITION
Definition: can_helper.h:76
#define CAN_BYTE_1_POSITION
Definition: can_helper.h:72
Database module header.
#define DATA_READ_DATA(...)
Definition: database.h:86
@ DATA_BLOCK_ID_ERROR_STATE
Definition: database_cfg.h:89
@ DATA_BLOCK_ID_STATE_REQUEST
Definition: database_cfg.h:98
@ DATA_BLOCK_ID_CURRENT_SENSOR
Definition: database_cfg.h:82
DIAG_RETURNTYPE_e DIAG_Handler(DIAG_ID_e diagId, DIAG_EVENT_e event, DIAG_IMPACT_LEVEL_e impact, uint32_t data)
DIAG_Handler provides generic error handling, based on diagnosis group.
Definition: diag.c:246
Diagnosis driver header.
@ DIAG_EVENT_NOT_OK
Definition: diag_cfg.h:266
@ DIAG_EVENT_OK
Definition: diag_cfg.h:265
@ DIAG_SYSTEM
Definition: diag_cfg.h:278
@ DIAG_STRING
Definition: diag_cfg.h:279
@ DIAG_ID_CAN_CC_RESPONDING
Definition: diag_cfg.h:186
@ DIAG_ID_CAN_TIMING
Definition: diag_cfg.h:184
@ DIAG_ID_CURRENT_SENSOR_RESPONDING
Definition: diag_cfg.h:188
@ DIAG_ID_CAN_RX_QUEUE_FULL
Definition: diag_cfg.h:185
@ DIAG_ID_CAN_EC_RESPONDING
Definition: diag_cfg.h:187
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:250
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:129
STD_RETURN_TYPE_e
Definition: fstd_types.h:82
@ STD_NOT_OK
Definition: fstd_types.h:84
@ STD_OK
Definition: fstd_types.h:83
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:77
Header of task driver implementation.
volatile bool ftsk_allQueuesCreated
OS_QUEUE ftsk_canRxQueue
General macros and definitions for the whole platform.
#define GEN_REPEAT_U(x, n)
Macro that helps to generate a series of literals (for array initializers).
Definition: general.h:250
#define GEN_STRIP(x)
Definition: general.h:261
#define UNIT_TEST_WEAK_IMPL
Definition: general.h:95
@ OS_SUCCESS
Definition: os.h:83
OS_STD_RETURN_e OS_ReceiveFromQueue(OS_QUEUE xQueue, void *const pvBuffer, uint32_t ticksToWait)
Receive an item from a queue.
Definition: os_freertos.c:248
OS_STD_RETURN_e OS_SendToBackOfQueueFromIsr(OS_QUEUE xQueue, const void *const pvItemToQueue, long *const pxHigherPriorityTaskWoken)
Post an item to the back the provided queue during an ISR.
Definition: os_freertos.c:273
void OS_ExitTaskCritical(void)
Exit Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os_freertos.c:138
void OS_EnterTaskCritical(void)
Enter Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os_freertos.c:134
uint32_t OS_GetTickCount(void)
Returns OS based system tick value.
Definition: os_freertos.c:142
void PEX_SetPin(uint8_t portExpander, uint8_t pin)
sets pin to high.
Definition: pex.c:336
void PEX_SetPinDirectionOutput(uint8_t portExpander, uint8_t pin)
sets pin to input.
Definition: pex.c:409
Header for the driver for the NXP PCA9539 port expander module.
#define PEX_PORT_EXPANDER2
Definition: pex_cfg.h:76
CAN_NODE_s * canNode
Definition: can_cfg.h:170
uint8_t data[CAN_MAX_DLC]
Definition: can_cfg.h:173
CAN_IDENTIFIER_TYPE_e idType
Definition: can_cfg.h:172
CAN_IDENTIFIER_TYPE_e idType
Definition: can_cfg.h:198
canBASE_t * canNodeRegister
Definition: can_cfg.h:76
CAN_RxCallbackFunction_f callbackFunction
Definition: can_cfg.h:243
CAN_MESSAGE_PROPERTIES_s message
Definition: can_cfg.h:241
CAN_NODE_s * canNode
Definition: can_cfg.h:240
bool currentSensorCCPresent[BS_NR_OF_STRINGS]
Definition: can.h:85
bool currentSensorECPresent[BS_NR_OF_STRINGS]
Definition: can.h:86
bool currentSensorPresent[BS_NR_OF_STRINGS]
Definition: can.h:84
bool periodicEnable
Definition: can.h:83
CAN_TxCallbackFunction_f callbackFunction
Definition: can_cfg.h:232
CAN_MESSAGE_PROPERTIES_s message
Definition: can_cfg.h:230
CAN_TX_MESSAGE_TIMING_s timing
Definition: can_cfg.h:231
uint32_t timestampCurrent[BS_NR_OF_STRINGS]
Definition: database_cfg.h:219
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:214
uint32_t timestampEnergyCounting[BS_NR_OF_STRINGS]
Definition: database_cfg.h:234
uint32_t timestampCurrentCounting[BS_NR_OF_STRINGS]
Definition: database_cfg.h:230
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:332
uint32_t previousTimestamp
Definition: database_cfg.h:124
DATA_BLOCK_ID_e uniqueId
Definition: database_cfg.h:122
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:530