foxBMS  1.6.0
The foxBMS Battery Management System API Documentation
sps.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 sps.c
44  * @author foxBMS Team
45  * @date 2020-10-14 (date of creation)
46  * @updated 2023-10-12 (date of last update)
47  * @version v1.6.0
48  * @ingroup DRIVERS
49  * @prefix SPS
50  *
51  * @brief Driver for the smart power switches.
52  *
53  */
54 
55 /*========== Includes =======================================================*/
56 #include "general.h"
57 
58 #include "sps.h"
59 
60 #include "database.h"
61 #include "io.h"
62 #include "mcu.h"
63 #include "os.h"
64 #include "pex.h"
65 #include "spi.h"
66 
67 #include <math.h>
68 #include <stdint.h>
69 
70 /*========== Macros and Definitions =========================================*/
71 
72 /*========== Static Constant and Variable Definitions =======================*/
73 /** state indicator of the state-machine */
75 
76 /** timer for the state-machine */
77 static uint8_t sps_timer = 0;
78 
79 /** SPI buffer:
80  * Tx part used to issue a write or read register command
81  * Rx part is unused
82  * @{
83  */
86 /**@}*/
87 
88 /** SPI buffer:
89  * Tx part used to write to contactor output control register
90  * Rx part used to read answer from former read register command
91  *
92  * When a read register command was issued on the MOSI line,
93  * the answers comes during the next command (read or write)
94  * on the MISO line
95  * (data sheet figure 6 page 9 in data sheet Rev. 2 - 11 September 2019)
96  *
97  * In the SPS driver, there are always two communications with the SPS IC
98  * each time the state machine is triggered:
99  * - first a register access (read or write)
100  * - then a write access to the channel output control register
101  * This way, the channel outputs are switched each time the state machine
102  * is triggered, and during the second access, if a read access was done
103  * before, the answer comes during the second access.
104  * @{
105  */
108 /**@}*/
109 
110 /** amount of ticks to wait when toggling the reset */
111 #define SPS_RESET_WAIT_TIME_TICKS (5u)
112 
113 /*========== Extern Constant and Variable Definitions =======================*/
114 
115 /*========== Static Function Prototypes =====================================*/
116 
117 /**
118  * @brief Assemble a general command to the SPS ICs
119  * @details For each call of the #SPS_Ctrl() function two transactions are
120  * sent. For details please read the documentation of #SPS_Transmit().
121  *
122  * This function has to be called before the transaction in order to
123  * update the TX buffer with a general command to the SPS chips in the
124  * daisy-chain. The actual command (and with that registers) that
125  * shall be accessed and sent is controlled by the parameter that is
126  * passed on with this function. *
127  * @param[in] action decides which command should be used
128  */
129 static void SPS_SetCommandTxBuffer(const SPS_ACTION_e action);
130 
131 /**
132  * @brief Assemble an update to the channel state of the SPS ICs
133  * @details For each call of the #SPS_Ctrl() function two transactions are
134  * sent. For details please read the documentation of #SPS_Transmit().
135  *
136  * This function has to be called before the transaction in order to
137  * update the TX buffer with a channel configuration to the SPS chips
138  * in the daisy-chain. The actual contactor or channel state is taken
139  * from the current state of the array #sps_channelStatus.
140  */
141 static void SPS_SetContactorsTxBuffer(void);
142 
143 /**
144  * @brief Transmit all assembled messages for one timeframe
145  * @details This function leverages the fact that the SPS are connected in a
146  * "daisy-chain". This way the chain acts as a large shift register.
147  * When sending a message into the chain it is clocked in until every
148  * chip in the chain as its message. Then chip-select is released and
149  * the messages parsed. The answer is then assembled by the chip in
150  * its register and clocked out and received by the master with the
151  * next transmission.
152  *
153  * This function sends out a general command to each chip that has
154  * been assembled with #SPS_SetCommandTxBuffer(). The clocked out
155  * information that is received of this transaction is stored in a
156  * separate buffer and is the answer from the last transaction of the
157  * timeframe before the current one.
158  *
159  * After this transaction the answer to the general command is
160  * retrieved and the transmission is used to clock in an update of the
161  * state of the contactor channels. This update has been assembled
162  * before the call of this function with the function
163  * #SPS_SetContactorsTxBuffer().
164  * @returns returns STD_OK if both transactions have been successful
165  */
166 static STD_RETURN_TYPE_e SPS_Transmit(void);
167 
168 /**
169  * @brief Read the current measurements for a specific output
170  * for all SPS ICs of the daisy-chain.
171  * @details A read command must be issued for all SPS ICs in the daisy chain
172  * first. There is one register to read for each output.
173  * This funcion i used to retrieve the answer on the MISO line
174  * after the write command to the contactors output registers
175  * was made.
176  * The result is written to SPS_CoilCurrent[].
177  * @param[in] outputAllDevices Output (1 to 4) to be read. Value between
178  * 1-4 instead of 0-3 to match numbering
179  * in data sheet.
180  * @return TODO
181  */
182 static void SPS_GlobalReadCurrent(const uint8_t outputAllDevices);
183 
184 /** initialize the IO ports for the contactor driver */
185 static void SPS_InitializeIo(void);
186 
187 /** Init TX buffers with 0 */
188 static void SPS_InitializeBuffers(void);
189 /**
190  * @brief Sets the SPI Tx buffer for a register read access
191  * for all SPS ICs of the daisy-chain.
192  * @details The same command is issued for all SPS ICs in the daisy chain.
193  * This means that the same register is read
194  * to all SPS ICs in the daisy chain.
195  * @param[in] address address of register accessed
196  * @param[in] controlOrDiagnostic type of read access,
197  * #SPS_READ_DIAGNOSTIC_REGISTER for diagnostic
198  * register, #SPS_READ_CONTROL_REGISTER for
199  * control register.
200  * @param[out] pSpiTxBuffer Tx buffer used for the transmission
201  */
202 static void SPS_GlobalRegisterRead(
203  const uint16_t address,
204  const SPS_READ_TYPE_e controlOrDiagnostic,
205  uint16_t *pSpiTxBuffer);
206 
207 /**
208  * @brief Sets the SPI Tx buffer for a register write access
209  * for all SPS ICs of the daisy-chain.
210  * @details The same command is issued for all SPS ICs in the daisy chain.
211  * This means that the same value is written
212  * to all SPS ICs in the daisy chain.
213  * The current value in register is overwritten by writeData.
214  *
215  * @param[in] address address of register accessed
216  * @param[in] writeData data to write
217  * @param[out] pSpiTxBuffer Tx buffer used for the transmission
218  */
219 static void SPS_GlobalRegisterWrite(const uint16_t address, uint8_t writeData, uint16_t *pSpiTxBuffer);
220 
221 /**
222  * @brief Sets the SPI Tx buffer for a register write access
223  * for a specific single SPS ICs in the daisy-chain.
224  * @details The same command is issued for all SPS ICs in the daisy chain.
225  * This means that the same value is written
226  * to all SPS ICs in the daisy chain.
227  * This function does not set the Tx buffer to 0.
228  * This must be done manually.
229  * @param[in] device device number in the daisy-chain to be written to.
230  * @param[in] address address of register accessed
231  * @param[in] writeData data to write. In case of read access, this
232  * field is ignored and can be set to 0u.
233  * @param[in] writeType defines whether the value in register should be
234  * replaced by writeData, or or-ed with writeType,
235  * or and-ed with writeData
236  * @param[out] pSpiTxBuffer Tx buffer used for the transmission
237  */
239  uint8_t device,
240  const uint16_t address,
241  uint8_t writeData,
242  SPS_WRITE_TYPE_e writeType,
243  uint16_t *pSpiTxBuffer);
244 
245 /**
246  * @brief Request the functional state of a channel
247  * @details Pass a value of #SPS_CHANNEL_FUNCTION_e and a channel index number
248  * in order to request this state.
249  * @param[in] channelIndex number of the channel that should be accessed;
250  * do not confuse with contactor channel!
251  * @param[in] channelFunction requested functional state of the channel
252  */
253 static void SPS_RequestChannelState(SPS_CHANNEL_INDEX channelIndex, SPS_CHANNEL_FUNCTION_e channelFunction);
254 
255 /*========== Static Function Implementations ================================*/
256 static void SPS_InitializeIo(void) {
257  /** Pin to drive reset line of SPS ICs */
258  SPS_RESET_GIO_PORT_DIR |= (uint32)((uint32)1u << SPS_RESET_PIN);
259  /** Pin to drive Chip Select line of SPS ICs */
260  SPI_SPS_CS_GIOPORT_DIR |= (uint32)((uint32)1u << SPI_SPS_CS_PIN);
261 
262  /* set feedback enable as output */
264  /* enable output on feedback enable */
266 }
267 
269  const uint16_t address,
270  const SPS_READ_TYPE_e controlOrDiagnostic,
271  uint16_t *pSpiTxBuffer) {
272  FAS_ASSERT(pSpiTxBuffer != NULL_PTR);
273  if (controlOrDiagnostic == SPS_READ_DIAGNOSTIC_REGISTER) {
274  for (uint8_t i = 0u; i < SPS_SPI_BUFFERSIZE; i++) {
275  /* R/W bit = 0 to read */
276  pSpiTxBuffer[i] = (address << SPS_ADDRESS_BIT_START); /* Register address */
277  }
278  } else if (controlOrDiagnostic == SPS_READ_CONTROL_REGISTER) {
279  for (uint8_t i = 0u; i < SPS_SPI_BUFFERSIZE; i++) {
280  pSpiTxBuffer[i] = (address << SPS_ADDRESS_BIT_START) | /* Register address */
281  ((uint16_t)1u << SPS_DIAG_CTRL_BIT_POSITION); /* Select diagnostic register */
282  }
283  } else {
284  /* Invalid access type */
286  }
287 }
288 
289 static void SPS_GlobalRegisterWrite(const uint16_t address, uint8_t writeData, uint16_t *pSpiTxBuffer) {
290  FAS_ASSERT(pSpiTxBuffer != NULL_PTR);
291  for (uint8_t i = 0u; i < SPS_SPI_BUFFERSIZE; i++) {
292  pSpiTxBuffer[i] = ((uint16_t)1u << SPS_RW_BIT_POSITION) | /* R/W bit = 1 to write */
293  (address << SPS_ADDRESS_BIT_START) | /* Register address */
294  (writeData); /* Data to write */
295  }
296 }
297 
299  uint8_t device,
300  const uint16_t address,
301  uint8_t writeData,
302  SPS_WRITE_TYPE_e writeType,
303  uint16_t *pSpiTxBuffer) {
304  FAS_ASSERT(pSpiTxBuffer != NULL_PTR);
305  /* The index (SPS_SPI_BUFFERSIZE - 1 - device) is used because the devices
306  in the daisy-chain are accessed like a shift register. The first message
307  sent to the daisy-chain will arrive to the last device and the last
308  message will arrive to the first device. To communicate with
309  devices 0-1-2 in the daisy-chain, the sequence 2-1-0 has to be sent.
310  */
311  /* Keep the previous data which lies in the lower 8 bits */
312  uint8_t preceedingWriteData = (uint8_t)((pSpiTxBuffer[(SPS_SPI_BUFFERSIZE - 1u - device)]) & 0xFFu);
313  /* Clear write data which will be replaced */
314  pSpiTxBuffer[(SPS_SPI_BUFFERSIZE - 1u - device)] &= 0xFF00u;
315  /* Write R/W bit and address in the higher 8 bits */
316  pSpiTxBuffer[(SPS_SPI_BUFFERSIZE - 1u - device)] = (uint16_t)(
317  ((uint16_t)1u << SPS_RW_BIT_POSITION) | /* R/W bit = 1 to write */
318  (address << SPS_ADDRESS_BIT_START)); /* Register address */
319 
320  if (writeType == SPS_replaceCurrentValue) {
321  pSpiTxBuffer[(SPS_SPI_BUFFERSIZE - 1u - device)] |= (uint16_t)writeData; /* Data to write */
322  } else if (writeType == SPS_orWithCurrentValue) {
323  pSpiTxBuffer[(SPS_SPI_BUFFERSIZE - 1u - device)] |=
324  ((uint16_t)preceedingWriteData | (uint16_t)writeData); /* Data to write */
325  } else if (writeType == SPS_andWithCurrentValue) {
326  pSpiTxBuffer[(SPS_SPI_BUFFERSIZE - 1u - device)] |=
327  ((uint16_t)preceedingWriteData & (uint16_t)writeData); /* Data to write */
328  } else {
329  /* Invalid write type */
331  }
332 }
333 
334 static void SPS_SetCommandTxBuffer(const SPS_ACTION_e action) {
335  switch (action) {
339  /* transition to Normal mode and set drive strength to strong (This is required for high speed!) */
342  break;
343 
347  0x000F, /* Measure all four outputs for current and voltage on demand*/
349  break;
350 
354  break;
355 
359  break;
360 
364  break;
365 
369  break;
370 
374  break;
375 
376  default:
377  for (uint8_t i = 0u; i < SPS_SPI_BUFFERSIZE; i++) {
378  sps_spiTxRegisterBuffer[i] = 0x00;
379  }
380  break;
381  }
382 }
383 
384 static void SPS_InitializeBuffers(void) {
385  for (uint8_t i = 0u; i < SPS_SPI_BUFFERSIZE; i++) {
386  sps_spiTxRegisterBuffer[i] = 0u;
388  i,
390  0u, /* data to write, output control */
391  SPS_replaceCurrentValue, /* replace because we want to initialize with 0 */
393  }
394 }
395 
396 static void SPS_SetContactorsTxBuffer(void) {
397  for (SPS_CHANNEL_INDEX channel = 0u; channel < SPS_NR_OF_AVAILABLE_SPS_CHANNELS; channel++) {
398  SPS_CHANNEL_STATE_s *pChannel = &sps_channelStatus[channel];
399  /* If channel state is changed by request, process request */
400  if (pChannel->channelRequested != pChannel->channel) {
401  pChannel->channel = pChannel->channelRequested;
402 
403  /**
404  * With this computation, the contactor number is linked to the SPS IC
405  * position in the daisy-chain which is driving this contactor.
406  * Contactor 0-3: SPS IC 0
407  * Contactor 4-7: SPS IC 1
408  * Contactor 8-11: SPS IC 2
409  * ...
410  */
411  uint8_t spsDevicePositionInDaisyChain = channel / SPS_NR_CONTACTOR_PER_IC;
412 
413  if (pChannel->channelRequested == SPS_CHANNEL_ON) {
415  spsDevicePositionInDaisyChain,
417  1u << (channel % SPS_NR_CONTACTOR_PER_IC), /* data to write, output control */
418  SPS_orWithCurrentValue, /* OR because we want to set additional bits to 1 */
420  } else if (pChannel->channelRequested == SPS_CHANNEL_OFF) {
421  uint8_t writeData = (~(1u << (channel % SPS_NR_CONTACTOR_PER_IC)) & 0xFFu);
423  spsDevicePositionInDaisyChain,
425  writeData, /* data to write, output control */
426  SPS_andWithCurrentValue, /* AND because we want to set additional bits to 0 */
428  } else {
429  /* invalid entry in sps_channelStatus! */
431  }
432  }
433  }
434 }
435 
439 
440  /* The chip select has to be high for at least 300ns according to data sheet. This code delays
441  for the smallest time available in #MCU_Delay_us() which is 1us. After this time we can
442  be sure that the SPI interface is able to receive again. */
443  MCU_Delay_us(1u);
444 
450 
451  STD_RETURN_TYPE_e retVal = STD_NOT_OK;
452  if ((retVal1 == STD_OK) && (retVal2 == STD_OK)) {
453  retVal = STD_OK;
454  }
455  return retVal;
456 }
457 
458 static void SPS_GlobalReadCurrent(const uint8_t outputAllDevices) {
459  /* outputAllDevices has to be 1, 2, 3 or 4 */
460  FAS_ASSERT((outputAllDevices > 0u) && (outputAllDevices <= SPS_NR_CONTACTOR_PER_IC));
461  for (SPS_CHANNEL_INDEX channel = 0u; channel < SPS_NR_OF_AVAILABLE_SPS_CHANNELS; channel++) {
462  if ((channel % SPS_NR_CONTACTOR_PER_IC) == (outputAllDevices - 1u)) {
463  uint8_t buffer_position = channel / SPS_NR_CONTACTOR_PER_IC;
464  uint16_t buffer = sps_spiRxReadAnswerDuringChannelControl[(SPS_SPI_BUFFERSIZE - 1u - buffer_position)] &
466  sps_channelStatus[channel].current_mA = (float_t)buffer * SPS_I_MEASUREMENT_LSB_mA;
467  }
468  }
469 }
470 
471 static void SPS_RequestChannelState(SPS_CHANNEL_INDEX channelIndex, SPS_CHANNEL_FUNCTION_e channelFunction) {
473  FAS_ASSERT((channelFunction == SPS_CHANNEL_OFF) || (channelFunction == SPS_CHANNEL_ON));
474 
476  sps_channelStatus[channelIndex].channelRequested = channelFunction;
478 }
479 
480 /*========== Extern Function Implementations ================================*/
481 extern void SPS_Ctrl(void) {
482  if (sps_timer > 0u) {
483  sps_timer--;
484  }
485  STD_RETURN_TYPE_e transmitRetval = STD_NOT_OK;
486 
487  if (sps_timer == 0u) {
488  switch (sps_state) {
489  case SPS_START:
490  /* set SPI speed to low speed in order to safely reach the all SPS */
494  break;
495 
496  case SPS_RESET_LOW:
500  break;
501 
502  case SPS_RESET_HIGH:
506  break;
507 
511  transmitRetval = SPS_Transmit();
512  if (transmitRetval == STD_OK) {
514  /* we have successfully configured the control registers to
515  strong drive mode and can now go to high speed communication */
517  } else {
519  }
520  break;
521 
525  transmitRetval = SPS_Transmit();
526  if (transmitRetval == STD_OK) {
528  } else {
530  }
531  break;
532 
533  case SPS_READ_EN_IRQ_PIN:
536  transmitRetval = SPS_Transmit();
537  if (transmitRetval == STD_OK) {
539  } else {
541  }
542  break;
543 
547  transmitRetval = SPS_Transmit();
548  if (transmitRetval == STD_OK) {
550  } else {
552  }
554  break;
555 
559  transmitRetval = SPS_Transmit();
560  if (transmitRetval == STD_OK) {
562  } else {
564  }
566  break;
567 
571  transmitRetval = SPS_Transmit();
572  if (transmitRetval == STD_OK) {
574  } else {
576  }
578  break;
579 
583  transmitRetval = SPS_Transmit();
584  if (transmitRetval == STD_OK) {
586  } else {
588  }
590  break;
591  default:
593  break; /* LCOV_EXCL_LINE */
594  }
595  }
596 }
597 
598 extern void SPS_Initialize(void) {
600 }
601 
602 extern void SPS_RequestContactorState(SPS_CHANNEL_INDEX channelIndex, SPS_CHANNEL_FUNCTION_e channelFunction) {
604  /* AXIVION Routine Generic-MissingParameterAssert: channelFunction: parameter accepts all defined enums */
605  /* Allow only contactor related SPS outputs to be operated with this function */
606  const SPS_CHANNEL_AFFILIATION_e channelAffiliation = SPS_GetChannelAffiliation(channelIndex);
607  FAS_ASSERT(SPS_AFF_CONTACTOR == channelAffiliation);
608  SPS_RequestChannelState(channelIndex, channelFunction);
609 }
610 
611 extern void SPS_RequestGeneralIoState(SPS_CHANNEL_INDEX channelIndex, SPS_CHANNEL_FUNCTION_e channelFunction) {
613  /* AXIVION Routine Generic-MissingParameterAssert: channelFunction: parameter accepts all defined enums */
614  /* Allow only general IO related SPS outputs to be operated with this function */
615  const SPS_CHANNEL_AFFILIATION_e channelAffiliation = SPS_GetChannelAffiliation(channelIndex);
616  FAS_ASSERT(SPS_AFF_GENERAL_IO == channelAffiliation);
617  SPS_RequestChannelState(channelIndex, channelFunction);
618 }
619 
622 
624 
626  float_t channelCurrent_mA = sps_channelStatus[channelIndex].current_mA;
628 
629  if (channelCurrent_mA > sps_channelStatus[channelIndex].thresholdFeedbackOn_mA) {
630  channelFeedback = CONT_SWITCH_ON;
631  }
632 
633  return channelFeedback;
634 }
635 
636 extern CONT_ELECTRICAL_STATE_TYPE_e SPS_GetChannelPexFeedback(const SPS_CHANNEL_INDEX channelIndex, bool normallyOpen) {
638  FAS_ASSERT((normallyOpen == true) || (normallyOpen == false));
639 
640  SPS_CHANNEL_FEEDBACK_MAPPING_s channelMapping = sps_kChannelFeedbackMapping[channelIndex];
641  uint8_t pinState = PEX_GetPin(channelMapping.pexDevice, channelMapping.pexChannel);
642 
644  if (normallyOpen == true) {
645  /* contactor is on if pinstate is high */
646  if (pinState != PEX_PIN_LOW) {
647  channelFeedback = CONT_SWITCH_ON;
648  }
649  } else {
650  /* contactor is on if pinstate is low */
651  if (pinState != PEX_PIN_HIGH) {
652  channelFeedback = CONT_SWITCH_ON;
653  }
654  }
655 
656  return channelFeedback;
657 }
658 
661  return sps_channelStatus[channelIndex].affiliation;
662 }
663 
664 /*========== Externalized Static Function Implementations (Unit Test) =======*/
665 #ifdef UNITY_UNIT_TEST
666 extern void TEST_SPS_RequestChannelState(SPS_CHANNEL_INDEX channelIndex, SPS_CHANNEL_FUNCTION_e channelFunction) {
667  SPS_RequestChannelState(channelIndex, channelFunction);
668 }
669 extern SPS_STATE_e TEST_SPS_GetSpsState(void) {
670  return sps_state;
671 }
672 extern void TEST_SPS_SetSpsState(const SPS_STATE_e newState) {
673  sps_state = newState;
674 }
675 extern uint8_t TEST_SPS_GetSpsTimer(void) {
676  return sps_timer;
677 }
678 extern void TEST_SPS_SetSpsTimer(const uint8_t newTimer) {
679  sps_timer = newTimer;
680 }
681 #endif
CONT_ELECTRICAL_STATE_TYPE_e
Definition: contactor_cfg.h:70
@ CONT_SWITCH_ON
Definition: contactor_cfg.h:72
@ CONT_SWITCH_OFF
Definition: contactor_cfg.h:71
Database module header.
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:255
#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
General macros and definitions for the whole platform.
#define GEN_SET_BIT(register, bit)
sets a bit to 1u
Definition: general.h:72
void IO_PinSet(volatile uint32_t *pRegisterAddress, uint32_t pin)
Set pin by writing in pin output register.
Definition: io.c:91
void IO_PinReset(volatile uint32_t *pRegisterAddress, uint32_t pin)
Reset pin by writing in pin output register.
Definition: io.c:98
Header for the driver for the IO module.
void MCU_Delay_us(uint32_t delay_us)
Wait blocking a certain time in microseconds.
Definition: mcu.c:89
Headers for the driver for the MCU module.
Declaration of the OS wrapper interface.
void OS_ExitTaskCritical(void)
Exit Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os_freertos.c:154
void OS_EnterTaskCritical(void)
Enter Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os_freertos.c:150
uint8_t PEX_GetPin(uint8_t portExpander, uint8_t pin)
get pin state of port expander pins.
Definition: pex.c:366
Header for the driver for the NXP PCA9539 port expander module.
#define PEX_PIN_LOW
Definition: pex.h:67
#define PEX_PIN_HIGH
Definition: pex.h:68
STD_RETURN_TYPE_e SPI_TransmitReceiveData(SPI_INTERFACE_CONFIG_s *pSpiInterface, uint16 *pTxBuff, uint16 *pRxBuff, uint32 frameLength)
Transmits and receives data on SPI without DMA.
Definition: spi.c:221
Headers for the driver for the SPI module.
void SPI_SpsInterfaceSwitchToLowSpeed(SPI_INTERFACE_CONFIG_s *pSpiSpsInterface)
Switch the SPS spi handle to low speed.
Definition: spi_cfg.c:285
void SPI_SpsInterfaceSwitchToHighSpeed(SPI_INTERFACE_CONFIG_s *pSpiSpsInterface)
Switch the SPS spi handle to high speed.
Definition: spi_cfg.c:280
SPI_INTERFACE_CONFIG_s spi_spsInterface
Definition: spi_cfg.c:246
#define SPI_SPS_CS_GIOPORT_DIR
Definition: spi_cfg.h:154
#define SPI_SPS_CS_PIN
Definition: spi_cfg.h:155
CONT_ELECTRICAL_STATE_TYPE_e SPS_GetChannelPexFeedback(const SPS_CHANNEL_INDEX channelIndex, bool normallyOpen)
Get the feedback state of a channel.
Definition: sps.c:636
#define SPS_RESET_WAIT_TIME_TICKS
Definition: sps.c:111
SPS_CHANNEL_AFFILIATION_e SPS_GetChannelAffiliation(SPS_CHANNEL_INDEX channelIndex)
Returns the channel affiliation.
Definition: sps.c:659
void SPS_Initialize(void)
Initialize IOs for the SPS driver.
Definition: sps.c:598
static void SPS_InitializeIo(void)
Definition: sps.c:256
static STD_RETURN_TYPE_e SPS_Transmit(void)
Transmit all assembled messages for one timeframe.
Definition: sps.c:436
static void SPS_GlobalReadCurrent(const uint8_t outputAllDevices)
Read the current measurements for a specific output for all SPS ICs of the daisy-chain.
Definition: sps.c:458
static void SPS_GlobalRegisterRead(const uint16_t address, const SPS_READ_TYPE_e controlOrDiagnostic, uint16_t *pSpiTxBuffer)
Sets the SPI Tx buffer for a register read access for all SPS ICs of the daisy-chain.
Definition: sps.c:268
static uint16_t sps_spiRxRegisterBuffer[SPS_SPI_BUFFERSIZE]
Definition: sps.c:85
void SPS_Ctrl(void)
Control function for the CONT driver state machine.
Definition: sps.c:481
static void SPS_SingleDeviceRegisterWrite(uint8_t device, const uint16_t address, uint8_t writeData, SPS_WRITE_TYPE_e writeType, uint16_t *pSpiTxBuffer)
Sets the SPI Tx buffer for a register write access for a specific single SPS ICs in the daisy-chain.
Definition: sps.c:298
static void SPS_InitializeBuffers(void)
Definition: sps.c:384
static void SPS_GlobalRegisterWrite(const uint16_t address, uint8_t writeData, uint16_t *pSpiTxBuffer)
Sets the SPI Tx buffer for a register write access for all SPS ICs of the daisy-chain.
Definition: sps.c:289
static uint8_t sps_timer
Definition: sps.c:77
static void SPS_SetContactorsTxBuffer(void)
Assemble an update to the channel state of the SPS ICs.
Definition: sps.c:396
CONT_ELECTRICAL_STATE_TYPE_e SPS_GetChannelCurrentFeedback(const SPS_CHANNEL_INDEX channelIndex)
Get feedback value.
Definition: sps.c:620
void SPS_RequestContactorState(SPS_CHANNEL_INDEX channelIndex, SPS_CHANNEL_FUNCTION_e channelFunction)
Request state of a contactor.
Definition: sps.c:602
static uint16_t sps_spiTxRegisterBuffer[SPS_SPI_BUFFERSIZE]
Definition: sps.c:84
static SPS_STATE_e sps_state
Definition: sps.c:74
static uint16_t sps_spiTxWriteToChannelChannelControlRegister[SPS_SPI_BUFFERSIZE]
Definition: sps.c:106
static uint16_t sps_spiRxReadAnswerDuringChannelControl[SPS_SPI_BUFFERSIZE]
Definition: sps.c:107
static void SPS_RequestChannelState(SPS_CHANNEL_INDEX channelIndex, SPS_CHANNEL_FUNCTION_e channelFunction)
Request the functional state of a channel.
Definition: sps.c:471
static void SPS_SetCommandTxBuffer(const SPS_ACTION_e action)
Assemble a general command to the SPS ICs.
Definition: sps.c:334
void SPS_RequestGeneralIoState(SPS_CHANNEL_INDEX channelIndex, SPS_CHANNEL_FUNCTION_e channelFunction)
Request state of a general IO.
Definition: sps.c:611
Headers for the driver for the smart power switches.
SPS_CHANNEL_STATE_s sps_channelStatus[SPS_NR_OF_AVAILABLE_SPS_CHANNELS]
Definition: sps_cfg.c:68
const SPS_CHANNEL_FEEDBACK_MAPPING_s sps_kChannelFeedbackMapping[SPS_NR_OF_AVAILABLE_SPS_CHANNELS]
Definition: sps_cfg.c:85
#define SPS_FEEDBACK_GIO_PORT_DIR
Definition: sps_cfg.h:77
#define SPS_OUTPUT_CONTROL_REGISTER_ADDRESS
Definition: sps_cfg.h:122
#define SPS_ISR_IRQ_DIAG_REGISTER_ADDRESS
Definition: sps_cfg.h:126
#define SPS_GLOBAL_CONTROL_REGISTER_ADDRESS
Definition: sps_cfg.h:121
#define SPS_NR_OF_AVAILABLE_SPS_CHANNELS
Definition: sps_cfg.h:102
#define SPS_SPI_BUFFERSIZE
Definition: sps_cfg.h:118
#define SPS_OD_IOUT1_DIAG_REGISTER_ADDRESS
Definition: sps_cfg.h:128
#define SPS_NORMAL_MODE
Definition: sps_cfg.h:150
#define SPS_STRONG_DRIVE
Definition: sps_cfg.h:152
#define SPS_FEEDBACK_GIO_PORT
Definition: sps_cfg.h:76
#define SPS_RESET_GIO_PORT_DIR
Definition: sps_cfg.h:71
#define SPS_DRIVE_STRENGTH_BIT_START
Definition: sps_cfg.h:161
SPS_READ_TYPE_e
Definition: sps_cfg.h:180
@ SPS_READ_DIAGNOSTIC_REGISTER
Definition: sps_cfg.h:181
@ SPS_READ_CONTROL_REGISTER
Definition: sps_cfg.h:182
#define SPS_MODE_BIT_START
Definition: sps_cfg.h:159
#define SPS_OD_IOUT2_DIAG_REGISTER_ADDRESS
Definition: sps_cfg.h:129
SPS_ACTION_e
Definition: sps_cfg.h:226
@ SPS_ACTION_READ_CURRENT_MEASUREMENT2
Definition: sps_cfg.h:230
@ SPS_ACTION_READ_CURRENT_MEASUREMENT1
Definition: sps_cfg.h:229
@ SPS_ACTION_TRIGGER_CURRENT_MEASUREMENT
Definition: sps_cfg.h:228
@ SPS_ACTION_READ_EN_IRQ_PIN
Definition: sps_cfg.h:233
@ SPS_ACTION_READ_CURRENT_MEASUREMENT4
Definition: sps_cfg.h:232
@ SPS_ACTION_CONFIGURE_CONTROL_REGISTER
Definition: sps_cfg.h:227
@ SPS_ACTION_READ_CURRENT_MEASUREMENT3
Definition: sps_cfg.h:231
SPS_CHANNEL_FUNCTION_e
Definition: sps_cfg.h:186
@ SPS_CHANNEL_ON
Definition: sps_cfg.h:188
@ SPS_CHANNEL_OFF
Definition: sps_cfg.h:187
#define SPS_NR_CONTACTOR_PER_IC
Definition: sps_cfg.h:82
#define SPS_RW_BIT_POSITION
Definition: sps_cfg.h:139
#define SPS_OD_IOUT4_DIAG_REGISTER_ADDRESS
Definition: sps_cfg.h:131
#define SPS_OD_IOUT3_DIAG_REGISTER_ADDRESS
Definition: sps_cfg.h:130
#define SPS_ADDRESS_BIT_START
Definition: sps_cfg.h:145
SPS_WRITE_TYPE_e
Definition: sps_cfg.h:173
@ SPS_andWithCurrentValue
Definition: sps_cfg.h:176
@ SPS_orWithCurrentValue
Definition: sps_cfg.h:175
@ SPS_replaceCurrentValue
Definition: sps_cfg.h:174
#define SPS_RESET_GIO_PORT
Definition: sps_cfg.h:70
#define SPS_DIAG_CTRL_BIT_POSITION
Definition: sps_cfg.h:147
#define SPS_I_MEASUREMENT_LSB_mA
Definition: sps_cfg.h:164
#define SPS_RESET_PIN
Definition: sps_cfg.h:72
#define SPS_BITMASK_DIAGNOSTIC_ONDEMAND_OUTPUT_CURRENT
Definition: sps_cfg.h:170
#define SPS_C_CONTROL_REGISTER_ADDRESS
Definition: sps_cfg.h:123
SPS_STATE_e
Definition: sps_cfg.h:212
@ SPS_TRIGGER_CURRENT_MEASUREMENT
Definition: sps_cfg.h:217
@ SPS_CONFIGURE_CONTROL_REGISTER
Definition: sps_cfg.h:216
@ SPS_READ_MEASURED_CURRENT2
Definition: sps_cfg.h:219
@ SPS_READ_MEASURED_CURRENT1
Definition: sps_cfg.h:218
@ SPS_RESET_LOW
Definition: sps_cfg.h:214
@ SPS_READ_EN_IRQ_PIN
Definition: sps_cfg.h:222
@ SPS_READ_MEASURED_CURRENT3
Definition: sps_cfg.h:220
@ SPS_START
Definition: sps_cfg.h:213
@ SPS_READ_MEASURED_CURRENT4
Definition: sps_cfg.h:221
@ SPS_RESET_HIGH
Definition: sps_cfg.h:215
#define SPS_FEEDBACK_PIN
Definition: sps_cfg.h:78
uint8_t SPS_CHANNEL_INDEX
Definition: sps_types.h:65
SPS_CHANNEL_AFFILIATION_e
affiliation type of a sps channel
Definition: sps_types.h:73
@ SPS_AFF_CONTACTOR
Definition: sps_types.h:74
@ SPS_AFF_GENERAL_IO
Definition: sps_types.h:75
SPS_CHANNEL_FUNCTION_e channelRequested
Definition: sps_cfg.h:193
float_t current_mA
Definition: sps_cfg.h:195
SPS_CHANNEL_FUNCTION_e channel
Definition: sps_cfg.h:194
const SPS_CHANNEL_AFFILIATION_e affiliation
Definition: sps_cfg.h:197