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