foxBMS  1.1.1
The foxBMS Battery Management System API Documentation
sps.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2021, 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 2021-07-14 (date of last update)
47  * @ingroup DRIVERS
48  * @prefix SPS
49  *
50  * @brief Driver for the smart power switches.
51  *
52  */
53 
54 /*========== Includes =======================================================*/
55 #include "sps.h"
56 
57 #include "database.h"
58 #include "io.h"
59 #include "mcu.h"
60 #include "os.h"
61 #include "spi.h"
62 
63 /*========== Macros and Definitions =========================================*/
64 
65 /*========== Static Constant and Variable Definitions =======================*/
66 /** state indicator of the state-machine */
68 
69 /** timer for the state-machine */
70 static uint8_t sps_timer = 0;
71 
72 /** SPI buffer:
73  * Tx part used to issue a write or read register command
74  * Rx part is unused
75  * @{
76  */
79 /**@}*/
80 
81 /** SPI buffer:
82  * Tx part used to write to contactor output control register
83  * Rx part used to read answer from former read register command
84  *
85  * When a read register command was issued on the MOSI line,
86  * the answers comes during the next command (read or write)
87  * on the MISO line
88  * (datasheet figure 6 page 9 in datasheet Rev. 2 - 11 September 2019)
89  *
90  * In the SPS driver, there are always two communications with the SPS IC
91  * each time the state machine is triggered:
92  * - first a register access (read or write)
93  * - then a write access to the channel output control register
94  * This way, the channel outputs are switched each time the state machine
95  * is triggered, and during the second access, if a read access was done
96  * before, the answer comes during the second access.
97  * @{
98  */
101 /**@}*/
102 
103 /** amount of ticks to wait when toggling the reset */
104 #define SPS_RESET_WAIT_TIME_TICKS (5u)
105 
106 /*========== Extern Constant and Variable Definitions =======================*/
107 
108 /*========== Static Function Prototypes =====================================*/
109 
110 /**
111  * @brief Assemble a general command to the SPS ICs
112  * @details For each call of the #SPS_Ctrl() function two transactions are
113  * sent. For details please read the documentation of #SPS_Transmit().
114  *
115  * This function has to be called before the transaction in order to
116  * update the TX buffer with a general command to the SPS chips in the
117  * daisy-chain. The actual command (and with that registers) that
118  * shall be accessed and sent is controlled by the parameter that is
119  * passed on with this function. *
120  * @param[in] action decides which command should be used
121  */
122 static void SPS_SetCommandTxBuffer(const SPS_ACTION_e action);
123 
124 /**
125  * @brief Assemble an update to the channel state of the SPS ICs
126  * @details For each call of the #SPS_Ctrl() function two transactions are
127  * sent. For details please read the documentation of #SPS_Transmit().
128  *
129  * This function has to be called before the transaction in order to
130  * update the TX buffer with a channel configuration to the SPS chips
131  * in the daisy-chain. The actual contactor or channel state is taken
132  * from the current state of the array #sps_channelStatus.
133  */
134 static void SPS_SetContactorsTxBuffer(void);
135 
136 /**
137  * @brief Transmit all assembled messages for one timeframe
138  * @details This function leverages the fact that the SPS are connected in a
139  * "daisy-chain". This way the chain acts as a large shift register.
140  * When sending a message into the chain it is clocked in until every
141  * chip in the chain as its message. Then chip-select is released and
142  * the messages parsed. The answer is then assembled by the chip in
143  * its register and clocked out and received by the master with the
144  * next transmission.
145  *
146  * This function sends out a general command to each chip that has
147  * been assembled with #SPS_SetCommandTxBuffer(). The clocked out
148  * information that is received of this transaction is stored in a
149  * separate buffer and is the answer from the last transaction of the
150  * timeframe before the current one.
151  *
152  * After this transaction the answer to the general command is
153  * retrieved and the transmission is used to clock in an update of the
154  * state of the contactor channels. This update has been assembled
155  * before the call of this function with the function
156  * #SPS_SetContactorsTxBuffer().
157  * @returns returns STD_OK if both transactions have been successful
158  */
159 static STD_RETURN_TYPE_e SPS_Transmit(void);
160 
161 /**
162  * @brief Read the current measurements for a specific output
163  * for all SPS ICs of the daisy-chain.
164  * @details A read command must be issued for all SPS ICs in the daisy chain
165  * first. There is one register to read for each output.
166  * This funcion i used to retrieve the answer on the MISO line
167  * after the write command to the contactors output registers
168  * was made.
169  * The result is written to SPS_CoilCurrent[].
170  * @param[in] outputAllDevices Output (1 to 4) to be read. Value between
171  * 1-4 instead of 0-3 to match numbering
172  * in datasheet.
173  * @return TODO
174  */
175 static void SPS_GlobalReadCurrent(const uint8_t outputAllDevices);
176 
177 /** initialize the IO ports for the contactor driver */
178 static void SPS_InitializeIo(void);
179 
180 /** Init TX buffers with 0 */
181 static void SPS_InitializeBuffers(void);
182 /**
183  * @brief Sets the SPI Tx buffer for a register read access
184  * for all SPS ICs of the daisy-chain.
185  * @details The same command is issued for all SPS ICs in the daisy chain.
186  * This means that the same register is read
187  * to all SPS ICs in the daisy chain.
188  * @param[in] address address of register accessed
189  * @param[in] controlOrDiagnostic type of read access,
190  * #SPS_READ_DIAGNOSTIC_REGISTER for diagnostic
191  * register, #SPS_READ_CONTROL_REGISTER for
192  * control register.
193  * @param[out] pSpiTxBuffer Tx buffer used for the transmission
194  */
195 static void SPS_GlobalRegisterRead(
196  const uint16_t address,
197  const SPS_READ_TYPE_e controlOrDiagnostic,
198  uint16_t *pSpiTxBuffer);
199 
200 /**
201  * @brief Sets the SPI Tx buffer for a register write access
202  * for all SPS ICs of the daisy-chain.
203  * @details The same command is issued for all SPS ICs in the daisy chain.
204  * This means that the same value is written
205  * to all SPS ICs in the daisy chain.
206  * The current value in register is overwritten by writeData.
207  *
208  * @param[in] address address of register accessed
209  * @param[in] writeData data to write
210  * @param[out] pSpiTxBuffer Tx buffer used for the transmission
211  */
212 static void SPS_GlobalRegisterWrite(const uint16_t address, uint8_t writeData, uint16_t *pSpiTxBuffer);
213 
214 /**
215  * @brief Sets the SPI Tx buffer for a register write access
216  * for a specific single SPS ICs in the daisy-chain.
217  * @details The same command is issued for all SPS ICs in the daisy chain.
218  * This means that the same value is written
219  * to all SPS ICs in the daisy chain.
220  * This function does not set the Tx buffer to 0.
221  * This must be done manually.
222  * @param[in] device device number in the daisy-chain to be written to.
223  * @param[in] address address of register accessed
224  * @param[in] writeData data to write. In case of read access, this
225  * field is ignored and can be set to 0u.
226  * @param[in] writeType defines wether the value in register should be
227  * replaced by writeData, or or-ed with writeType,
228  * or and-ed with writeData
229  * @param[out] pSpiTxBuffer Tx buffer used for the transmission
230  */
232  uint8_t device,
233  const uint16_t address,
234  uint8_t writeData,
235  SPS_WRITE_TYPE_e writeType,
236  uint16_t *pSpiTxBuffer);
237 
238 /**
239  * @brief Request the functional state of a channel
240  * @details Pass a value of #SPS_CHANNEL_FUNCTION_e and a channel index number
241  * in order to request this state.
242  * @param[in] channelIndex number of the channel that should be accessed;
243  * do not confuse with contactor channel!
244  * @param[in] channelFunction requested functional state of the channel
245  */
246 static void SPS_RequestChannelState(SPS_CHANNEL_INDEX channelIndex, SPS_CHANNEL_FUNCTION_e channelFunction);
247 
248 /*========== Static Function Implementations ================================*/
249 static void SPS_InitializeIo(void) {
250  /** Pin to drive reset line of SPS ICs */
251  SPS_RESET_GIOPORT_DIR |= (uint32)((uint32)1u << SPS_RESET_PIN);
252  /** Pin to drive Chip Select line of SPS ICs */
253  SPS_SPI_CS_GIOPORT_DIR |= (uint32)((uint32)1u << SPS_SPI_CS_PIN);
254 }
255 
257  const uint16_t address,
258  const SPS_READ_TYPE_e controlOrDiagnostic,
259  uint16_t *pSpiTxBuffer) {
260  FAS_ASSERT(pSpiTxBuffer != NULL_PTR);
261  if (controlOrDiagnostic == SPS_READ_DIAGNOSTIC_REGISTER) {
262  for (uint8_t i = 0u; i < SPS_SPI_BUFFERSIZE; i++) {
263  /* R/W bit = 0 to read */
264  pSpiTxBuffer[i] = (address << SPS_ADDRESS_BIT_START); /* Register address */
265  }
266  } else if (controlOrDiagnostic == SPS_READ_CONTROL_REGISTER) {
267  for (uint8_t i = 0u; i < SPS_SPI_BUFFERSIZE; i++) {
268  pSpiTxBuffer[i] = (address << SPS_ADDRESS_BIT_START) | /* Register address */
269  (1u << SPS_DIAG_CTRL_BIT_POSITION); /* Select diagnostic register */
270  }
271  } else {
272  /* Invalid access type */
274  }
275 }
276 
277 static void SPS_GlobalRegisterWrite(const uint16_t address, uint8_t writeData, uint16_t *pSpiTxBuffer) {
278  FAS_ASSERT(pSpiTxBuffer != NULL_PTR);
279  for (uint8_t i = 0u; i < SPS_SPI_BUFFERSIZE; i++) {
280  pSpiTxBuffer[i] = (1u << SPS_RW_BIT_POSITION) | /* R/W bit = 1 to write */
281  (address << SPS_ADDRESS_BIT_START) | /* Register address */
282  (writeData); /* Data to write */
283  }
284 }
285 
287  uint8_t device,
288  const uint16_t address,
289  uint8_t writeData,
290  SPS_WRITE_TYPE_e writeType,
291  uint16_t *pSpiTxBuffer) {
292  FAS_ASSERT(pSpiTxBuffer != NULL_PTR);
293  /* The index (SPS_SPI_BUFFERSIZE - 1 - device) is used because the devices
294  in the daisy-chain are accessed like a shift register. The first message
295  sent to the daisy-chain will arrive to the last device and the last
296  message will arrive to the first device. To communicate with
297  devices 0-1-2 in the daisy-chain, the sequence 2-1-0 has to be sent.
298  */
299  /* Keep the previous data which lies in the lower 8 bits */
300  uint8_t preceedingWriteData = (pSpiTxBuffer[(SPS_SPI_BUFFERSIZE - 1u - device)]) & 0xFFu;
301  /* Clear write data which will be replaced */
302  pSpiTxBuffer[(SPS_SPI_BUFFERSIZE - 1u - device)] &= 0xFF00u;
303  /* Write R/W bit and address in the higher 8 bits */
304  pSpiTxBuffer[(SPS_SPI_BUFFERSIZE - 1u - device)] = (1u << SPS_RW_BIT_POSITION) | /* R/W bit = 1 to write */
305  (address << SPS_ADDRESS_BIT_START); /* Register address */
306 
307  if (writeType == SPS_replaceCurrentValue) {
308  pSpiTxBuffer[(SPS_SPI_BUFFERSIZE - 1u - device)] |= writeData; /* Data to write */
309  } else if (writeType == SPS_orWithCurrentValue) {
310  pSpiTxBuffer[(SPS_SPI_BUFFERSIZE - 1u - device)] |= preceedingWriteData | writeData; /* Data to write */
311  } else if (writeType == SPS_andWithCurrentValue) {
312  pSpiTxBuffer[(SPS_SPI_BUFFERSIZE - 1u - device)] |= preceedingWriteData & writeData; /* Data to write */
313  } else {
314  /* Invalid write type */
316  }
317 }
318 
319 static void SPS_SetCommandTxBuffer(const SPS_ACTION_e action) {
320  switch (action) {
324  /* transition to Normal mode and set drive strength to strong (This is required for high speed!) */
327  break;
328 
332  0x000F, /* Measure all four outputs for current and voltage on demand*/
334  break;
335 
339  break;
340 
344  break;
345 
349  break;
350 
354  break;
355 
359  break;
360 
361  default:
362  for (uint8_t i = 0u; i < SPS_SPI_BUFFERSIZE; i++) {
363  sps_spiTxRegisterBuffer[i] = 0x00;
364  }
365  break;
366  }
367 }
368 
369 static void SPS_InitializeBuffers() {
370  for (uint8_t i = 0u; i < SPS_SPI_BUFFERSIZE; i++) {
371  sps_spiTxRegisterBuffer[i] = 0u;
373  i,
375  0u, /* data to write, output control */
376  SPS_replaceCurrentValue, /* replace because we want to initialize with 0 */
378  }
379 }
380 
381 static void SPS_SetContactorsTxBuffer(void) {
382  for (SPS_CHANNEL_INDEX channel = 0u; channel < SPS_NR_OF_AVAILABLE_SPS_CHANNELS; channel++) {
383  SPS_CHANNEL_STATE_s *pChannel = &sps_channelStatus[channel];
384  /* If channel state is changed by request, process request */
385  if (pChannel->channelRequested != pChannel->channel) {
386  pChannel->channel = pChannel->channelRequested;
387 
388  /**
389  * With this computation, the contactor number is linked to the SPS IC
390  * position in the daisy-chain which is driving this contactor.
391  * Contactor 0-3: SPS IC 0
392  * Contactor 4-7: SPS IC 1
393  * Contactor 8-11: SPS IC 2
394  * ...
395  */
396  uint8_t spsDevicePositionInDaisyChain = channel / SPS_NR_CONTACTOR_PER_IC;
397 
398  if (pChannel->channelRequested == SPS_CHANNEL_ON) {
400  spsDevicePositionInDaisyChain,
402  1u << (channel % SPS_NR_CONTACTOR_PER_IC), /* data to write, output control */
403  SPS_orWithCurrentValue, /* OR because we want to set additional bits to 1 */
405  } else if (pChannel->channelRequested == SPS_CHANNEL_OFF) {
406  uint8_t writeData = ~(1u << (channel % SPS_NR_CONTACTOR_PER_IC));
408  spsDevicePositionInDaisyChain,
410  writeData, /* data to write, output control */
411  SPS_andWithCurrentValue, /* AND because we want to set additional bits to 0 */
413  } else {
414  /* invalid entry in sps_channelStatus! */
416  }
417  }
418  }
419 }
420 
424 
425  /* The chip select has to be high for at least 300ns according to datasheet. This code delays
426  for the smallest time available in #MCU_delay_us() which is 1us. After this time we can
427  be sure that the SPI interface is able to receive again. */
428  MCU_delay_us(1u);
429 
435 
436  STD_RETURN_TYPE_e retVal = STD_NOT_OK;
437  if ((STD_OK == retVal1) && (STD_OK == retVal2)) {
438  retVal = STD_OK;
439  }
440  return retVal;
441 }
442 
443 static void SPS_GlobalReadCurrent(const uint8_t outputAllDevices) {
444  /* outputAllDevices has to be 1, 2, 3 or 4 */
445  FAS_ASSERT((outputAllDevices > 0u) && (outputAllDevices <= SPS_NR_CONTACTOR_PER_IC));
446  for (SPS_CHANNEL_INDEX channel = 0u; channel < SPS_NR_OF_AVAILABLE_SPS_CHANNELS; channel++) {
447  if ((channel % SPS_NR_CONTACTOR_PER_IC) == (outputAllDevices - 1u)) {
448  uint8_t buffer_position = channel / SPS_NR_CONTACTOR_PER_IC;
449  uint16_t buffer = sps_spiRxReadAnswerDuringChannelControl[(SPS_SPI_BUFFERSIZE - 1u - buffer_position)] &
451  sps_channelStatus[channel].current_mA = (float)buffer * SPS_I_MEASUREMENT_LSB_mA;
452  }
453  }
454 }
455 
456 static void SPS_RequestChannelState(SPS_CHANNEL_INDEX channelIndex, SPS_CHANNEL_FUNCTION_e channelFunction) {
458  FAS_ASSERT((SPS_CHANNEL_OFF == channelFunction) || (SPS_CHANNEL_ON == channelFunction));
459 
461  sps_channelStatus[channelIndex].channelRequested = channelFunction;
463 }
464 
465 /*========== Extern Function Implementations ================================*/
466 extern void SPS_Ctrl(void) {
467  if (sps_timer > 0u) {
468  sps_timer--;
469  }
470  STD_RETURN_TYPE_e transmitRetval = STD_NOT_OK;
471 
472  if (sps_timer == 0u) {
473  switch (sps_state) {
474  case SPS_START:
475  /* set SPI speed to low speed in order to safely reach the all SPS */
479  break;
480 
481  case SPS_RESET_LOW:
485  break;
486 
487  case SPS_RESET_HIGH:
491  break;
492 
496  transmitRetval = SPS_Transmit();
497  if (STD_OK == transmitRetval) {
499  /* we have successfully configured the control registers to
500  strong drive mode and can now go to high speed communication */
502  } else {
504  }
505  break;
506 
510  transmitRetval = SPS_Transmit();
511  if (STD_OK == transmitRetval) {
513  } else {
515  }
516  break;
517 
518  case SPS_READ_EN_IRQ_PIN:
521  transmitRetval = SPS_Transmit();
522  if (STD_OK == transmitRetval) {
524  } else {
526  }
527  break;
528 
532  transmitRetval = SPS_Transmit();
533  if (STD_OK == transmitRetval) {
535  } else {
537  }
539  break;
540 
544  transmitRetval = SPS_Transmit();
545  if (STD_OK == transmitRetval) {
547  } else {
549  }
551  break;
552 
556  transmitRetval = SPS_Transmit();
557  if (STD_OK == transmitRetval) {
559  } else {
561  }
563  break;
564 
568  transmitRetval = SPS_Transmit();
569  if (STD_OK == transmitRetval) {
571  } else {
573  }
575  break;
576  default:
578  break;
579  }
580  }
581 }
582 
583 extern void SPS_Initialize(void) {
585 }
586 
587 extern void SPS_RequestContactorState(SPS_CHANNEL_INDEX channelIndex, SPS_CHANNEL_FUNCTION_e channelFunction) {
589  SPS_RequestChannelState(channelIndex, channelFunction);
590 }
591 
592 extern void SPS_RequestGeneralIOState(SPS_CHANNEL_INDEX channelIndex, SPS_CHANNEL_FUNCTION_e channelFunction) {
594  SPS_RequestChannelState(channelIndex, channelFunction);
595 }
596 
599 
601 
603  float channelCurrent_mA = sps_channelStatus[channelIndex].current_mA;
605 
606  if (channelCurrent_mA > sps_channelStatus[channelIndex].thresholdFeedbackOn_mA) {
607  channelFeedback = CONT_SWITCH_ON;
608  }
609 
610  return channelFeedback;
611 }
612 
615  return sps_channelStatus[channelIndex].affiliation;
616 }
617 
618 /*========== Externalized Static Function Implementations (Unit Test) =======*/
619 #ifdef UNITY_UNIT_TEST
620 extern void TEST_SPS_RequestChannelState(SPS_CHANNEL_INDEX channelIndex, SPS_CHANNEL_FUNCTION_e channelFunction) {
621  SPS_RequestChannelState(channelIndex, channelFunction);
622 }
623 extern SPS_STATE_e TEST_SPS_GetSpsState(void) {
624  return sps_state;
625 }
626 extern void TEST_SPS_SetSpsState(const SPS_STATE_e newState) {
627  sps_state = newState;
628 }
629 extern uint8_t TEST_SPS_GetSpsTimer(void) {
630  return sps_timer;
631 }
632 extern void TEST_SPS_SetSpsTimer(const uint8_t newTimer) {
633  sps_timer = newTimer;
634 }
635 #endif /* UNITY_UNIT_TEST */
enum CONT_ELECTRICAL_STATE_TYPE CONT_ELECTRICAL_STATE_TYPE_e
@ 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:237
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:108
@ STD_NOT_OK
Definition: fstd_types.h:73
@ STD_OK
Definition: fstd_types.h:72
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:66
enum STD_RETURN_TYPE STD_RETURN_TYPE_e
void IO_PinSet(volatile uint32_t *pRegisterAddress, uint32_t pin)
Set pin by writing in pin output register.
Definition: io.c:70
void IO_PinReset(volatile uint32_t *pRegisterAddress, uint32_t pin)
Set pin by writing in pin output register.
Definition: io.c:77
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:80
Headers for the driver for the MCU module.
void OS_ExitTaskCritical(void)
Exit Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os.c:178
void OS_EnterTaskCritical(void)
Enter Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os.c:174
Implementation of the tasks used by the system, headers.
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:142
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:302
void SPI_SpsInterfaceSwitchToHighSpeed(SPI_INTERFACE_CONFIG_s *pSpiSpsInterface)
Switch the SPS spi handle to high speed.
Definition: spi_cfg.c:297
SPI_INTERFACE_CONFIG_s spi_spsInterface
Definition: spi_cfg.c:172
#define SPS_SPI_CS_GIOPORT_DIR
Definition: spi_cfg.h:74
#define SPS_SPI_CS_PIN
Definition: spi_cfg.h:75
#define SPS_RESET_WAIT_TIME_TICKS
Definition: sps.c:104
SPS_CHANNEL_AFFILIATION_e SPS_GetChannelAffiliation(SPS_CHANNEL_INDEX channelIndex)
Returns the channel affiliation.
Definition: sps.c:613
void SPS_Initialize(void)
Initialize IOs for the SPS driver.
Definition: sps.c:583
static void SPS_InitializeIo(void)
Definition: sps.c:249
static STD_RETURN_TYPE_e SPS_Transmit(void)
Transmit all assembled messages for one timeframe.
Definition: sps.c:421
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:443
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:256
static uint16_t sps_spiRxRegisterBuffer[SPS_SPI_BUFFERSIZE]
Definition: sps.c:78
void SPS_Ctrl(void)
Control function for the CONT driver state machine.
Definition: sps.c:466
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:286
static void SPS_InitializeBuffers(void)
Definition: sps.c:369
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:277
void SPS_RequestGeneralIOState(SPS_CHANNEL_INDEX channelIndex, SPS_CHANNEL_FUNCTION_e channelFunction)
Request state of a general IO.
Definition: sps.c:592
static uint8_t sps_timer
Definition: sps.c:70
static void SPS_SetContactorsTxBuffer(void)
Assemble an update to the channel state of the SPS ICs.
Definition: sps.c:381
void SPS_RequestContactorState(SPS_CHANNEL_INDEX channelIndex, SPS_CHANNEL_FUNCTION_e channelFunction)
Request state of a contactor.
Definition: sps.c:587
static uint16_t sps_spiTxRegisterBuffer[SPS_SPI_BUFFERSIZE]
Definition: sps.c:77
static SPS_STATE_e sps_state
Definition: sps.c:67
static uint16_t sps_spiTxWriteToChannelChannelControlRegister[SPS_SPI_BUFFERSIZE]
Definition: sps.c:99
static uint16_t sps_spiRxReadAnswerDuringChannelControl[SPS_SPI_BUFFERSIZE]
Definition: sps.c:100
static void SPS_RequestChannelState(SPS_CHANNEL_INDEX channelIndex, SPS_CHANNEL_FUNCTION_e channelFunction)
Request the functional state of a channel.
Definition: sps.c:456
static void SPS_SetCommandTxBuffer(const SPS_ACTION_e action)
Assemble a general command to the SPS ICs.
Definition: sps.c:319
CONT_ELECTRICAL_STATE_TYPE_e SPS_GetChannelFeedback(SPS_CHANNEL_INDEX channelIndex)
Get feedback value.
Definition: sps.c:597
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:63
#define SPS_OUTPUT_CONTROL_REGISTER_ADDRESS
Definition: sps_cfg.h:102
#define SPS_GLOBAL_CONTROL_REGISTER_ADDRESS
Definition: sps_cfg.h:101
#define SPS_NR_OF_AVAILABLE_SPS_CHANNELS
Definition: sps_cfg.h:82
@ SPS_CHANNEL_ON
Definition: sps_cfg.h:168
@ SPS_CHANNEL_OFF
Definition: sps_cfg.h:167
#define SPS_SPI_BUFFERSIZE
Definition: sps_cfg.h:98
#define SPS_OD_IOUT1_DIAG_REGISTER_ADDRESS
Definition: sps_cfg.h:106
@ SPS_TRIGGER_CURRENT_MEASUREMENT
Definition: sps_cfg.h:191
@ SPS_CONFIGURE_CONTROL_REGISTER
Definition: sps_cfg.h:190
@ SPS_READ_MEASURED_CURRENT2
Definition: sps_cfg.h:193
@ SPS_READ_MEASURED_CURRENT1
Definition: sps_cfg.h:192
@ SPS_RESET_LOW
Definition: sps_cfg.h:188
@ SPS_READ_EN_IRQ_PIN
Definition: sps_cfg.h:196
@ SPS_READ_MEASURED_CURRENT3
Definition: sps_cfg.h:194
@ SPS_START
Definition: sps_cfg.h:187
@ SPS_READ_MEASURED_CURRENT4
Definition: sps_cfg.h:195
@ SPS_RESET_HIGH
Definition: sps_cfg.h:189
#define SPS_NORMAL_MODE
Definition: sps_cfg.h:130
enum SPS_WRITE_TYPE SPS_WRITE_TYPE_e
#define SPS_STRONG_DRIVE
Definition: sps_cfg.h:132
enum SPS_ACTION SPS_ACTION_e
#define SPS_RESET_GIOPORT
Definition: sps_cfg.h:67
enum SPS_STATE SPS_STATE_e
#define SPS_DRIVE_STRENGTH_BIT_START
Definition: sps_cfg.h:141
@ SPS_andWithCurrentValue
Definition: sps_cfg.h:156
@ SPS_orWithCurrentValue
Definition: sps_cfg.h:155
@ SPS_replaceCurrentValue
Definition: sps_cfg.h:154
#define SPS_MODE_BIT_START
Definition: sps_cfg.h:139
#define SPS_OD_IOUT2_DIAG_REGISTER_ADDRESS
Definition: sps_cfg.h:107
#define SPS_RESET_GIOPORT_DIR
Definition: sps_cfg.h:68
#define SPS_NR_CONTACTOR_PER_IC
Definition: sps_cfg.h:73
@ SPS_READ_DIAGNOSTIC_REGISTER
Definition: sps_cfg.h:161
@ SPS_READ_CONTROL_REGISTER
Definition: sps_cfg.h:162
enum SPS_CHANNEL_FUNCTION SPS_CHANNEL_FUNCTION_e
#define SPS_RW_BIT_POSITION
Definition: sps_cfg.h:119
#define SPS_OD_IOUT4_DIAG_REGISTER_ADDRESS
Definition: sps_cfg.h:109
#define SPS_OD_IOUT3_DIAG_REGISTER_ADDRESS
Definition: sps_cfg.h:108
enum SPS_READ_TYPE SPS_READ_TYPE_e
#define SPS_ADDRESS_BIT_START
Definition: sps_cfg.h:125
#define SPS_EN_IRQ_PIN_DIAG_REGISTER_ADDRESS
Definition: sps_cfg.h:110
#define SPS_DIAG_CTRL_BIT_POSITION
Definition: sps_cfg.h:127
@ SPS_ACTION_READ_CURRENT_MEASUREMENT2
Definition: sps_cfg.h:204
@ SPS_ACTION_READ_CURRENT_MEASUREMENT1
Definition: sps_cfg.h:203
@ SPS_ACTION_TRIGGER_CURRENT_MEASUREMENT
Definition: sps_cfg.h:202
@ SPS_ACTION_READ_EN_IRQ_PIN
Definition: sps_cfg.h:207
@ SPS_ACTION_READ_CURRENT_MEASUREMENT4
Definition: sps_cfg.h:206
@ SPS_ACTION_CONFIGURE_CONTROL_REGISTER
Definition: sps_cfg.h:201
@ SPS_ACTION_READ_CURRENT_MEASUREMENT3
Definition: sps_cfg.h:205
#define SPS_I_MEASUREMENT_LSB_mA
Definition: sps_cfg.h:144
#define SPS_RESET_PIN
Definition: sps_cfg.h:69
#define SPS_BITMASK_DIAGNOSTIC_ONDEMAND_OUTPUT_CURRENT
Definition: sps_cfg.h:150
#define SPS_C_CONTROL_REGISTER_ADDRESS
Definition: sps_cfg.h:103
uint8_t SPS_CHANNEL_INDEX
Definition: sps_types.h:63
@ SPS_AFF_CONTACTOR
Definition: sps_types.h:72
@ SPS_AFF_GENERAL_IO
Definition: sps_types.h:73
enum SPS_CHANNEL_AFFILIATION SPS_CHANNEL_AFFILIATION_e
affiliation type of a sps channel
SPS_CHANNEL_FUNCTION_e channelRequested
Definition: sps_cfg.h:173
const SPS_CHANNEL_AFFILIATION_e affiliation
Definition: sps_cfg.h:177
float current_mA
Definition: sps_cfg.h:175
SPS_CHANNEL_FUNCTION_e channel
Definition: sps_cfg.h:174