foxBMS  1.4.1
The foxBMS Battery Management System API Documentation
nxp_mc33775a.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 nxp_mc33775a.c
44  * @author foxBMS Team
45  * @date 2020-05-08 (date of creation)
46  * @updated 2022-10-27 (date of last update)
47  * @version v1.4.1
48  * @ingroup DRIVERS
49  * @prefix N775
50  *
51  * @brief Driver for the MC33775A monitoring chip.
52  *
53  */
54 
55 /*========== Includes =======================================================*/
56 #include "nxp_mc33775a.h"
57 /* clang-format off */
58 #include "nxp_mc33775a-ll.h"
59 /* clang-format on */
60 
61 #include "HL_gio.h"
62 #include "HL_system.h"
63 #pragma diag_push
64 #pragma diag_suppress 232
65 #include "MC33775A.h"
66 #pragma diag_pop
67 
68 #include "afe_dma.h"
69 #include "database.h"
70 #include "diag.h"
71 #include "io.h"
72 #include "mcu.h"
73 #include "os.h"
74 #include "spi.h"
75 
76 /*========== Macros and Definitions =========================================*/
77 
78 /*========== Static Constant and Variable Definitions =======================*/
79 /** local copies of database tables */
80 /**@{*/
90 /**@}*/
93 
94 /*========== Extern Constant and Variable Definitions =======================*/
95 
97  .firstMeasurementMade = false,
98  .currentString = 0u,
99  .pSpiTxSequenceStart = NULL_PTR,
100  .pSpiTxSequence = NULL_PTR,
101  .pSpiRxSequenceStart = NULL_PTR,
102  .pSpiRxSequence = NULL_PTR,
103  .currentMux = {0},
104  .pMuxSequenceStart = {0},
105  .pMuxSequence = {0},
106  .n775Data.cellVoltage = &n775_cellVoltage,
107  .n775Data.cellTemperature = &n775_cellTemperature,
108  .n775Data.allGpioVoltage = &n775_allGpioVoltage,
109  .n775Data.minMax = &n775_minMax,
110  .n775Data.balancingFeedback = &n775_balancingFeedback,
111  .n775Data.balancingControl = &n775_balancingControl,
112  .n775Data.slaveControl = &n775_slaveControl,
113  .n775Data.openWire = &n775_openwire,
114  .n775Data.supplyCurrent = &n775_supplyCurrent,
115  .n775Data.errorTable = &n775_errorTable,
116 };
117 
118 /*========== Static Function Prototypes =====================================*/
119 static void N775_SetFirstMeasurementCycleFinished(N775_STATE_s *n775_state);
120 uint16_t n775_CrcAddItem(uint16_t remainder, uint16_t item);
121 uint16_t n775_CalcCrc(const N775_MESSAGE_s *msg);
122 
123 static void N775_InitializeDatabase(N775_STATE_s *n775_state);
124 void N775_ResetStringSequence(N775_STATE_s *n775_state);
126 void N775_ResetMuxIndex(N775_STATE_s *n775_state);
127 void N775_IncrementMuxIndex(N775_STATE_s *n775_state);
128 void N775_ErrorHandling(N775_STATE_s *n775_state, N775_COMMUNICATION_STATUS_e returnedValue, uint8_t module);
129 void N775_Init(N775_STATE_s *n775_state);
131 void N775_I2cInit(N775_STATE_s *n775_state);
132 void N775_StartMeasurement(N775_STATE_s *n775_state);
133 void N775_CaptureMeasurement(N775_STATE_s *n775_state);
135 void N775_BalanceSetup(N775_STATE_s *n775_state);
136 void N775_BalanceControl(N775_STATE_s *n775_state);
137 void N775_waitTime(uint32_t milliseconds);
138 
139 /*========== Static Function Implementations ================================*/
140 
141 /*========== Extern Function Implementations ================================*/
142 
143 /**
144  * @brief Called to calculate the CRC of a message.
145  *
146  * @param remainder
147  * @param item
148  *
149  * @return remainder
150  *
151  */
152 uint16_t n775_CrcAddItem(uint16_t remainder, uint16_t item) {
153  uint16_t local_remainder = remainder;
154 
155  local_remainder ^= item;
156 
157  for (int i = 0; i < 16; i++) {
158  /*
159  * Try to divide the current data bit.
160  */
161  if ((local_remainder & 0x8000u) > 0u) {
162  local_remainder = (local_remainder << 1u) ^ ((0x9eb2u << 1u) + 0x1u);
163  } else {
164  local_remainder = (local_remainder << 1u);
165  }
166  }
167 
168  return (local_remainder);
169 }
170 
171 /**
172  * @brief Calculate the CRC of a message.
173  *
174  * @param msg
175  *
176  * @return crc
177  *
178  */
179 uint16_t n775_CalcCrc(const N775_MESSAGE_s *msg) {
180  uint16_t remainder = 0;
181 
182  remainder = n775_CrcAddItem(remainder, msg->head);
183  remainder = n775_CrcAddItem(remainder, msg->dataHead);
184 
185  for (int i = 0; i < (msg->dataLength - 3); i++) {
186  remainder = n775_CrcAddItem(remainder, msg->data[i]);
187  }
188 
189  return (remainder);
190 }
191 
192 /**
193  * @brief in the database, initializes the fields related to the N775 driver.
194  *
195  * This function loops through all the N775-related data fields in the database
196  * and sets them to 0. It should be called in the initialization or re-initialization
197  * routine of the N775 driver.
198  *
199  * @param n775_state state of the N775A driver
200  *
201  */
202 static void N775_InitializeDatabase(N775_STATE_s *n775_state) {
203  uint16_t iterator = 0;
204 
205  for (uint8_t stringNumber = 0u; stringNumber < BS_NR_OF_STRINGS; stringNumber++) {
206  n775_state->n775Data.cellVoltage->state = 0;
207  n775_state->n775Data.minMax->minimumCellVoltage_mV[stringNumber] = 0;
208  n775_state->n775Data.minMax->maximumCellVoltage_mV[stringNumber] = 0;
209  n775_state->n775Data.minMax->nrModuleMinimumCellVoltage[stringNumber] = 0;
210  n775_state->n775Data.minMax->nrModuleMaximumCellVoltage[stringNumber] = 0;
211  n775_state->n775Data.minMax->nrCellMinimumCellVoltage[stringNumber] = 0;
212  n775_state->n775Data.minMax->nrCellMaximumCellVoltage[stringNumber] = 0;
213  for (iterator = 0u; iterator < BS_NR_OF_CELL_BLOCKS_PER_STRING; iterator++) {
214  n775_state->n775Data.cellVoltage->cellVoltage_mV[stringNumber][iterator] = 0;
215  }
216 
217  n775_state->n775Data.cellTemperature->state = 0;
218  n775_state->n775Data.minMax->minimumTemperature_ddegC[stringNumber] = 0;
219  n775_state->n775Data.minMax->maximumTemperature_ddegC[stringNumber] = 0;
220  n775_state->n775Data.minMax->nrModuleMinimumTemperature[stringNumber] = 0;
221  n775_state->n775Data.minMax->nrModuleMaximumTemperature[stringNumber] = 0;
222  n775_state->n775Data.minMax->nrSensorMinimumTemperature[stringNumber] = 0;
223  n775_state->n775Data.minMax->nrSensorMaximumTemperature[stringNumber] = 0;
224  for (iterator = 0u; iterator < BS_NR_OF_TEMP_SENSORS_PER_STRING; iterator++) {
225  n775_state->n775Data.cellTemperature->cellTemperature_ddegC[stringNumber][iterator] = 0;
226  }
227 
228  for (iterator = 0u; iterator < BS_NR_OF_CELL_BLOCKS_PER_STRING; iterator++) {
229  n775_state->n775Data.balancingControl->balancingState[stringNumber][iterator] = 0;
230  }
231  for (iterator = 0u; iterator < BS_NR_OF_MODULES_PER_STRING; iterator++) {
232  n775_state->n775Data.errorTable->communicationOk[stringNumber][iterator] = false;
233  n775_state->n775Data.errorTable->noCommunicationTimeout[stringNumber][iterator] = false;
234  n775_state->n775Data.errorTable->crcIsValid[stringNumber][iterator] = false;
235  n775_state->n775Data.errorTable->mux0IsOk[stringNumber][iterator] = false;
236  n775_state->n775Data.errorTable->mux1IsOK[stringNumber][iterator] = false;
237  n775_state->n775Data.errorTable->mux2IsOK[stringNumber][iterator] = false;
238  n775_state->n775Data.errorTable->mux3IsOK[stringNumber][iterator] = false;
239  }
240  for (iterator = 0u; iterator < BS_NR_OF_MODULES_PER_STRING; iterator++) {
241  n775_state->n775Data.uid[stringNumber][iterator] = 0;
242  }
243  }
244 
245  DATA_WRITE_DATA(n775_state->n775Data.cellVoltage);
247  DATA_WRITE_DATA(n775_state->n775Data.minMax);
249 }
250 
251 void N775_Meas(N775_STATE_s *n775_state) {
252  N775_InitializeDatabase(n775_state);
253  /* Initialize SPI sequence pointers */
256 
257  /* Initialize each string */
258  N775_ResetStringSequence(n775_state);
259  while (n775_state->currentString < BS_NR_OF_STRINGS) {
260  /* Initialize mux sequence pointers */
261  n775_state->pMuxSequenceStart[n775_state->currentString] = n775_muxSequence;
262  N775_Init(n775_state);
263  N775_IncrementStringSequence(n775_state);
264  }
265 
266  while (1) {
267  N775_ResetStringSequence(n775_state);
268 
269  while (n775_state->currentString < BS_NR_OF_STRINGS) {
270  if (N775_USE_MUX_FOR_TEMP == true) {
271  /* Set mux channel according to mux sequence */
272  N775_SetMuxChannel(n775_state);
273  }
274  N775_CaptureMeasurement(n775_state);
275  if (N775_USE_MUX_FOR_TEMP == true) {
276  /* Update index in mux sequence */
277  N775_IncrementMuxIndex(n775_state);
278  }
279  N775_BalanceControl(n775_state);
280 
281  for (uint8_t m = 0u; m < BS_NR_OF_MODULES_PER_STRING; m++) {
282  if (N775_IsFirstMeasurementCycleFinished(n775_state) == true) {
283  if (n775_state->n775Data.errorTable->noCommunicationTimeout[n775_state->currentString][m] == 0u) {
284  /* Daisy-chain does not answer: initialize it again */
285  n775_state->pMuxSequenceStart[n775_state->currentString] = n775_muxSequence;
286  N775_Init(n775_state);
287  /* Daisy-chain re-initialized: no need to check further slaves */
288  break;
289  }
290  }
291  }
292 
293  N775_IncrementStringSequence(n775_state);
294  }
295 
296  /* Set flag when all strings have been measured */
297  if ((n775_state->currentString == BS_NR_OF_STRINGS) &&
298  (N775_IsFirstMeasurementCycleFinished(n775_state) == 0u)) {
300  }
301  }
302 }
303 
304 /**
305  * @brief reset index in string sequence.
306  *
307  * @param n775_state state of the N775A driver
308  *
309  */
311  n775_state->currentString = 0u;
312  n775_state->pSpiTxSequence = n775_state->pSpiTxSequenceStart + n775_state->currentString;
313  n775_state->pSpiRxSequence = n775_state->pSpiRxSequenceStart + n775_state->currentString;
314 }
315 
316 /**
317  * @brief updates index in string sequence.
318  *
319  * @param n775_state state of the N775A driver
320  *
321  */
323  n775_state->currentString++;
324  n775_state->pSpiTxSequence = n775_state->pSpiTxSequenceStart + n775_state->currentString;
325  n775_state->pSpiRxSequence = n775_state->pSpiRxSequenceStart + n775_state->currentString;
326 }
327 
328 /**
329  * @brief resets index in mux sequence.
330  *
331  * @param n775_state state of the N775A driver
332  *
333  */
334 void N775_ResetMuxIndex(N775_STATE_s *n775_state) {
335  n775_state->currentMux[n775_state->currentString] = 0u;
336  n775_state->pMuxSequence[n775_state->currentString] = n775_state->pMuxSequenceStart[n775_state->currentString];
337 }
338 
339 /**
340  * @brief updates index in mux sequence.
341  *
342  * @param n775_state state of the N775A driver
343  *
344  */
346  n775_state->currentMux[n775_state->currentString]++;
347  if (n775_state->currentMux[n775_state->currentString] >= N775_MUX_SEQUENCE_LENGTH) {
348  n775_state->currentMux[n775_state->currentString] = 0u;
349  }
350  n775_state->pMuxSequence[n775_state->currentString] = n775_state->pMuxSequenceStart[n775_state->currentString] +
351  n775_state->currentMux[n775_state->currentString];
352 }
353 
354 /**
355  * @brief handles error when doing measurements.
356  *
357  * This function is used in the measurement function. It sets the errors flags in
358  * the error table according to the value returned by the communication function.
359  *
360  * @param n775_state state of the N775A driver
361  * @param returnedValue status of the low-level communication
362  * @param module number of module addressed
363  *
364  */
365 void N775_ErrorHandling(N775_STATE_s *n775_state, N775_COMMUNICATION_STATUS_e returnedValue, uint8_t module) {
366  if (returnedValue == N775_COMMUNICATION_OK) {
367  n775_state->n775Data.errorTable->communicationOk[n775_state->currentString][module] = true;
368  n775_state->n775Data.errorTable->noCommunicationTimeout[n775_state->currentString][module] = true;
369  n775_state->n775Data.errorTable->crcIsValid[n775_state->currentString][module] = true;
370  } else {
371  n775_state->n775Data.errorTable->communicationOk[n775_state->currentString][module] = false;
372  switch (returnedValue) {
374  n775_state->n775Data.errorTable->noCommunicationTimeout[n775_state->currentString][module] = false;
375  break;
377  n775_state->n775Data.errorTable->crcIsValid[n775_state->currentString][module] = false;
378  break;
379  default:
380  n775_state->n775Data.errorTable->communicationOk[n775_state->currentString][module] = false;
381  break;
382  }
383  }
384 }
385 
386 /**
387  * @brief initializes the N775 driver.
388  *
389  * This function enumerates the slaves and starts the measurement.
390  *
391  * @param n775_state state of the N775A driver
392  *
393  */
394 void N775_Init(N775_STATE_s *n775_state) {
395  FAS_ASSERT(n775_state != NULL_PTR);
396 
397  /* Reset mux sequence */
398  N775_ResetMuxIndex(n775_state);
399 
400  /* Initialize daisy-chain */
401  if (STD_OK != N775_Enumerate(n775_state)) {
402  /* error handling */}
403  N775_StartMeasurement(n775_state);
404  N775_I2cInit(n775_state);
405  N775_BalanceSetup(n775_state);
406 }
407 
408 /**
409  * @brief enumerates the N775 slaves.
410  *
411  * This function gives the slaves in the daisy-chain an address.
412  *
413  * @param n775_state state of the N775A driver
414  *
415  */
417  FAS_ASSERT(n775_state != NULL_PTR);
418  uint16_t readValue = 0u;
419  uint16_t uid[3u] = {0};
421  STD_RETURN_TYPE_e retVal = STD_NOT_OK;
422 
423  /** Parse all slaves in the daisy-chain */
424  for (uint8_t i = 1; i <= BS_NR_OF_MODULES_PER_STRING; i++) {
425  /* First send slave to deep sleep to reset message counter */
427  i,
428  MC33775_SYS_MODE_OFFSET,
429  (MC33775_SYS_MODE_TARGETMODE_DEEPSLEEP_ENUM_VAL << MC33775_SYS_MODE_TARGETMODE_POS),
430  n775_state->pSpiTxSequence);
431  N775_waitTime(1u);
432 
433  /* Wake up slave */
434  returnedValue = N775_CommunicationRead(i, MC33775_SYS_COM_CFG_OFFSET, &readValue, n775_state);
435  /* If slave is not enumerated */
436  if (returnedValue != N775_COMMUNICATION_OK) {
437  /* Wait until the slave has woken up */
439 
440  returnedValue = N775_CommunicationRead(i, MC33775_SYS_COM_CFG_OFFSET, &readValue, n775_state);
441  /* If slave is not enumerated */
442  if (returnedValue != N775_COMMUNICATION_OK) {
443  /* Enumerate slave */
445  (0u << 6u) + 0u,
446  MC33775_SYS_COM_CFG_OFFSET,
447  i + (N775_DEFAULT_CHAIN_ADDRESS << 6) +
448  (MC33775_SYS_COM_CFG_BUSFW_ENABLED_ENUM_VAL << MC33775_SYS_COM_CFG_BUSFW_POS),
449  n775_state->pSpiTxSequence);
450  }
451 
452  /* Reset the message counter of the driver */
454  /* Check that the device has been enumerated */
455  returnedValue = N775_CommunicationRead(i, MC33775_SYS_VERSION_OFFSET, &readValue, n775_state);
456  if (returnedValue == N775_COMMUNICATION_OK) {
457  retVal = STD_OK;
458  }
459  } else {
460  /* Slave already has an address */
461  retVal = STD_OK;
462  }
463 
464  /* Set timeout, enable/disable timeout */
466  i,
467  MC33775_SYS_COM_TO_CFG_OFFSET,
468  (N775_TIMEOUT_SWITCH << MC33775_SYS_COM_TO_CFG_COMTODISABLE_POS) |
469  (N775_TIMEOUT_TO_SLEEP_10MS << MC33775_SYS_COM_TO_CFG_COMTO_POS),
470  n775_state->pSpiTxSequence);
471 
472  /* read uid of each device */
473  returnedValue = N775_CommunicationReadMultiple(i, 3u, 3u, MC33775_SYS_UID_LOW_OFFSET, uid, n775_state);
474  if (returnedValue == N775_COMMUNICATION_OK) {
475  n775_state->n775Data.uid[n775_state->currentString][i - 1u] = 0u;
476  for (uint8_t j = 0u; j <= 3u; j++) {
477  n775_state->n775Data.uid[n775_state->currentString][i - 1u] |= ((uint64_t)uid[j]) << (16u * j);
478  }
479  }
480  }
481 
482  return retVal;
483 }
484 
485 /**
486  * @brief init I2C for the N775 slaves.
487  *
488  * This function makes slaves ready for I2C transactions with on-slave devices.
489  *
490  * @param n775_state state of the N775A driver
491  *
492  */
493 void N775_I2cInit(N775_STATE_s *n775_state) {
494  FAS_ASSERT(n775_state != NULL_PTR);
495  /* Enable the I2C module and select 400 kHz */
498  MC33775_I2C_CFG_OFFSET,
499  (MC33775_I2C_CFG_EN_ENABLED_ENUM_VAL << MC33775_I2C_CFG_EN_POS) +
500  (MC33775_I2C_CFG_CLKSEL_F_400K_ENUM_VAL << MC33775_I2C_CFG_CLKSEL_POS),
501  n775_state->pSpiTxSequence);
502 }
503 
504 /**
505  * @brief starts the measurement.
506  *
507  * The MC33775A measures continuously. This function
508  * starts the measurement.
509  *
510  * @param n775_state state of the N775A driver
511  *
512  */
514  FAS_ASSERT(n775_state != NULL_PTR);
515 
516  /* Enable cell voltage measurements */
517  N775_CommunicationWrite(N775_BROADCAST_ADDRESS, MC33775_ALLM_VCVB_CFG_OFFSET, 0x3FFF, n775_state->pSpiTxSequence);
518  /* Enable analog inputs 0-3 and module voltage measurement */
519  N775_CommunicationWrite(N775_BROADCAST_ADDRESS, MC33775_PRMM_AIN_CFG_OFFSET, 0x1F, n775_state->pSpiTxSequence);
520  /* Enable analog inputs 4-7 measurement */
521  N775_CommunicationWrite(N775_BROADCAST_ADDRESS, MC33775_SECM_AIN_CFG_OFFSET, 0x0F, n775_state->pSpiTxSequence);
522  /* Set pause of balancing before measurement start, enable the measurement units simultaneously */
525  MC33775_ALLM_CFG_OFFSET,
526  (N775_BALPAUSELEN_10US << MC33775_ALLM_CFG_BALPAUSELEN_POS) | (1 << MC33775_ALLM_CFG_MEASEN_POS),
527  n775_state->pSpiTxSequence);
528 
530 }
531 
532 /**
533  * @brief captures the measurement.
534  *
535  * The MC33775A measures continuously.
536  * This function takes a snapshot on all slaves in the daisy-chain.
537  *
538  * @param n775_state state of the N775A driver
539  *
540  */
542  FAS_ASSERT(n775_state != NULL_PTR);
543 
544  uint16_t primaryRawValues[20] = {0u};
545  uint16_t secondaryRawValues[4] = {0u};
546  uint16_t currentRawValue = 0u;
547  int16_t primaryValues[20] = {0u};
548  int16_t secondaryValues[4] = {0u};
549  int16_t currentValue = 0u;
553  uint16_t error = 0u;
554  bool gpio03Error = false;
555  bool gpio47Error = false;
556 
557  /* Send capture command. This ends the last cycle and starts a new one */
560  MC33775_ALLM_APP_CTRL_OFFSET,
561  (1u << MC33775_ALLM_APP_CTRL_PAUSEBAL_POS) | (0x3FFu << MC33775_PRMM_APP_CTRL_CAPVC_POS) |
562  (MC33775_PRMM_APP_CTRL_VCOLNUM_DISABLED_ENUM_VAL << MC33775_PRMM_APP_CTRL_VCOLNUM_POS),
563  n775_state->pSpiTxSequence);
564  /* Wait for measurements to take place */
566  /* Send capture command. This ends the last cycle and starts a new one */
569  MC33775_ALLM_APP_CTRL_OFFSET,
570  (0u << MC33775_ALLM_APP_CTRL_PAUSEBAL_POS) | (0x3FFu << MC33775_PRMM_APP_CTRL_CAPVC_POS) |
571  (MC33775_PRMM_APP_CTRL_VCOLNUM_DISABLED_ENUM_VAL << MC33775_PRMM_APP_CTRL_VCOLNUM_POS),
572  n775_state->pSpiTxSequence);
573  /* Wait for measurements to be ready */
575 
576  for (uint8_t m = 0u; m < BS_NR_OF_MODULES_PER_STRING; m++) {
577  uint8_t deviceAddress = m + 1u;
578  retValPrimary = N775_CommunicationReadMultiple(
579  deviceAddress, 20, 4u, MC33775_PRMM_APP_VC_CNT_OFFSET, primaryRawValues, n775_state);
580  retValSecondary = N775_CommunicationReadMultiple(
581  deviceAddress, 4, 4u, MC33775_SECM_APP_AIN4_OFFSET, secondaryRawValues, n775_state);
582  if (N775_CHECK_SUPPLY_CURRENT == true) {
583  retValSupplyCurrent =
584  N775_CommunicationRead(deviceAddress, MC33775_SECM_PER_NPNISENSE_OFFSET, &currentRawValue, n775_state);
585  }
586 
587  N775_ErrorHandling(n775_state, retValPrimary, m);
588  if (retValPrimary == N775_COMMUNICATION_OK) {
589  for (uint8_t c = 0u; c < BS_NR_OF_CELL_BLOCKS_PER_MODULE; c++) {
590  /* Store cell voltages */
591  if (N775_INVALID_REGISTER_VALUE != primaryRawValues[c + 1u]) {
592  primaryValues[c + 1u] = (int16_t)primaryRawValues[c + 1u];
593  n775_state->n775Data.cellVoltage
595  (((float)primaryValues[c + 1u]) * 154.0e-6f * 1000.0f);
596  } else {
597  error++;
598  }
599  }
600  for (uint8_t g = 0u; g < 4u; g++) {
601  /* Store GPIO voltages */
602  if (N775_INVALID_REGISTER_VALUE != primaryRawValues[g + 16u]) {
603  primaryValues[g + 16u] = (int16_t)primaryRawValues[g + 16u];
604  n775_state->n775Data.allGpioVoltage
605  ->gpioVoltages_mV[n775_state->currentString][g + (m * BS_NR_OF_GPIOS_PER_MODULE)] =
606  (((float)primaryValues[g + 16u]) * 154.0e-6f * 1000.0f);
607  } else {
608  gpio03Error = true;
609  error++;
610  }
611  }
612  /* Store module voltage */
613  if (N775_INVALID_REGISTER_VALUE != primaryRawValues[15u]) {
614  primaryValues[15u] = (int16_t)primaryRawValues[15u];
615  n775_state->n775Data.cellVoltage->moduleVoltage_mV[n775_state->currentString][m] =
616  (((float)primaryValues[15u]) * 2.58e-3f * 1000.0f);
617  } else {
618  error++;
619  }
620  }
621 
622  N775_ErrorHandling(n775_state, retValSecondary, m);
623  if (retValSecondary == N775_COMMUNICATION_OK) {
624  for (uint8_t g = 4u; g < 8u; g++) {
625  if (N775_INVALID_REGISTER_VALUE != secondaryRawValues[g - 4u]) {
626  secondaryValues[g - 4u] = (int16_t)secondaryRawValues[g - 4u];
627  n775_state->n775Data.allGpioVoltage
628  ->gpioVoltages_mV[n775_state->currentString][g + (m * BS_NR_OF_GPIOS_PER_MODULE)] =
629  (((float)secondaryValues[g - 4u]) * 154.0e-6f * 1000.0f);
630  } else {
631  gpio47Error = true;
632  error++;
633  }
634  }
635  }
636 
637  /* Set temperature values */
638  if (N775_USE_MUX_FOR_TEMP == true) {
639  /* Mux case */
640  if (gpio03Error == false) {
641  n775_state->n775Data.cellTemperature
642  ->cellTemperature_ddegC[n775_state->currentString]
643  [n775_state->currentMux[n775_state->currentString] +
646  n775_state->n775Data.allGpioVoltage
647  ->gpioVoltages_mV[n775_state->currentString]
649  }
650  } else if (N775_USE_MUX_FOR_TEMP == false) {
651  /* No mux case */
652  if ((gpio03Error == false) && (gpio47Error == false)) {
653  for (uint16_t t = 0u; t < BS_NR_OF_TEMP_SENSORS_PER_MODULE; t++) {
654  n775_state->n775Data.cellTemperature
657  n775_state->n775Data.allGpioVoltage
658  ->gpioVoltages_mV[n775_state->currentString][t + (m * BS_NR_OF_GPIOS_PER_MODULE)]);
659  }
660  }
661  } else {
662  /* Invalid value for switch case */
664  }
665 
666  if (N775_CHECK_SUPPLY_CURRENT == true) {
667  N775_ErrorHandling(n775_state, retValSupplyCurrent, m);
668  if (retValSupplyCurrent == N775_COMMUNICATION_OK) {
669  if (N775_INVALID_REGISTER_VALUE != currentRawValue) {
670  currentValue = (int16_t)currentRawValue;
671  n775_state->n775Data.supplyCurrent->current[n775_state->currentString][m] =
672  (((float)currentValue) * 7.69e-6f * 1000.0f);
673  } else {
674  error++;
675  }
676  }
677  }
678  }
679 
681  n775_state->n775Data.cellVoltage, n775_state->n775Data.cellTemperature, n775_state->n775Data.allGpioVoltage);
682 }
683 
684 /**
685  * @brief sets mux channel.
686  *
687  * This function uses I2C to set the mux channel.
688  *
689  * @param n775_state state of the N775A driver
690  *
691  */
693  FAS_ASSERT(n775_state != NULL_PTR);
694  FAS_ASSERT(n775_state->pMuxSequence[n775_state->currentString]->muxId < 4u);
695  FAS_ASSERT(n775_state->pMuxSequence[n775_state->currentString]->muxChannel <= 0xFFu);
696 
697  uint16_t readValue = 0u;
698  uint8_t dataI2c = 0u;
699  uint8_t addressI2c_write = N775_ADG728_ADDRESS_UPPERBITS;
700  uint8_t addressI2c_read = N775_ADG728_ADDRESS_UPPERBITS;
701  uint16_t timeout = 0u;
702  STD_RETURN_TYPE_e retVAL = STD_OK;
704 
705  /* First set channel */
706 
707  /* Set bit1 and bit0 with mux address, write to mux */
708  addressI2c_write |= ((n775_state->pMuxSequence[n775_state->currentString]->muxId) << 1u) | N775_I2C_WRITE;
709  /* Set bit1 and bit0 with mux address, read from mux */
710  addressI2c_read |= ((n775_state->pMuxSequence[n775_state->currentString]->muxId) << 1u) | N775_I2C_READ;
711 
712  /**
713  * Set data to send, contains channel bit (8 channels)
714  * 1 means channel active, 0 means channel inactive
715  */
716  if (n775_state->pMuxSequence[n775_state->currentString]->muxChannel == 0xFF) {
717  /* 0xFF in mux sequence means disable all channels */
718  dataI2c = 0u;
719  } else {
720  dataI2c = (uint8_t)(1u << (n775_state->pMuxSequence[n775_state->currentString]->muxChannel));
721  }
722 
723  /* Write data to send on I2C bus in registers */
726  MC33775_I2C_DATA0_OFFSET,
727  (addressI2c_write << MC33775_I2C_DATA0_BYTE0_POS) | (dataI2c << MC33775_I2C_DATA0_BYTE1_POS),
728  n775_state->pSpiTxSequence);
729 
730  /* Read with a repeated start directly after write */
733  MC33775_I2C_DATA1_OFFSET,
734  (addressI2c_read << MC33775_I2C_DATA1_BYTE2_POS) | (N775_I2C_DUMMY_BYTE << MC33775_I2C_DATA1_BYTE3_POS),
735  n775_state->pSpiTxSequence);
736 
737  /* Write into the control register to start transaction */
740  MC33775_I2C_CTRL_OFFSET,
741  (N775_I2C_NR_BYTES_FOR_MUX_WRITE << MC33775_I2C_CTRL_START_POS) |
742  ((MC33775_I2C_CTRL_STPAFTER_STOP_ENUM_VAL << MC33775_I2C_CTRL_STPAFTER_POS) +
743  (N775_I2C_NR_BYTES_TO_SWITCH_TO_READ_FOR_UX_READ << MC33775_I2C_CTRL_RDAFTER_POS)),
744  n775_state->pSpiTxSequence);
745 
746  /**
747  * Wait util transaction ends, test on last device in daisy-chain
748  * So device address = number of modules
749  */
750  timeout = N775_FLAG_READY_TIMEOUT;
751  do {
752  returnedValue =
753  N775_CommunicationRead(BS_NR_OF_MODULES_PER_STRING, MC33775_I2C_STAT_OFFSET, &readValue, n775_state);
754  timeout--;
755  } while ((readValue & MC33775_I2C_STAT_PENDING_MSK) && (returnedValue == N775_COMMUNICATION_OK) && (timeout > 0u));
756 
757  if (returnedValue == N775_COMMUNICATION_OK) {
758  /**
759  * Get I2C read data, on last device in daisy-chain
760  * Use result to set error state for all slaves to avoid
761  * reading all slaves in daisy-chain.
762  */
763  returnedValue =
764  N775_CommunicationRead(BS_NR_OF_MODULES_PER_STRING, MC33775_I2C_DATA1_OFFSET, &readValue, n775_state);
765  readValue = readValue >> MC33775_I2C_DATA1_BYTE3_POS;
766 
767  if (returnedValue == N775_COMMUNICATION_OK) {
768  if (N775_CHECK_MUX_STATE == true) {
769  if (readValue == dataI2c) {
770  /* OK */
771  for (uint8_t m = 0u; m < BS_NR_OF_MODULES_PER_STRING; m++) {
772  n775_state->n775Data.errorTable->mux0IsOk[n775_state->currentString][m] = true;
773  }
774  } else {
775  /* Not OK */
776  for (uint8_t m = 0u; m < BS_NR_OF_MODULES_PER_STRING; m++) {
777  n775_state->n775Data.errorTable->mux0IsOk[n775_state->currentString][m] = false;
778  }
779  }
780  } else {
781  retVAL = STD_NOT_OK;
782  }
783  }
784  } else {
785  retVAL = STD_NOT_OK;
786  }
787 
788  return retVAL;
789 }
790 
791 /**
792  * @brief setups balancing.
793  *
794  * Sets all balancing timer to max to allow for software balancing control.
795  *
796  * @param n775_state state of the N775A driver
797  *
798  */
799 void N775_BalanceSetup(N775_STATE_s *n775_state) {
800  FAS_ASSERT(n775_state != NULL_PTR);
801 
802  /* Set global timeout counter to max value */
805  MC33775_BAL_GLOB_TO_TMR_OFFSET,
807  n775_state->pSpiTxSequence);
808 
809  /* Disable pre-balancing timer by setting it to zero */
811  N775_BROADCAST_ADDRESS, MC33775_BAL_PRE_TMR_OFFSET, N775_PRE_BALANCING_TIMER, n775_state->pSpiTxSequence);
812 
813  /* Set PWM value for all channels to 100%, set balancing timer for all channels to maximum value */
816  MC33775_BAL_TMR_CH_ALL_OFFSET,
817  (MC33775_BAL_TMR_CH_ALL_PWM_PWM100_ENUM_VAL << MC33775_BAL_TMR_CH_ALL_PWM_POS) |
818  (N775_ALL_CHANNEL_BALANCING_TIMER << MC33775_BAL_TMR_CH_ALL_BALTIME_POS),
819  n775_state->pSpiTxSequence);
820 
821  /* Select timer based balancing and enable balancing */
824  MC33775_BAL_GLOB_CFG_OFFSET,
825  (MC33775_BAL_GLOB_CFG_BALEN_ENABLED_ENUM_VAL << MC33775_BAL_GLOB_CFG_BALEN_POS) |
826  (MC33775_BAL_GLOB_CFG_TMRBALEN_STOP_ENUM_VAL << MC33775_BAL_GLOB_CFG_TMRBALEN_POS),
827  n775_state->pSpiTxSequence);
828 }
829 
830 /**
831  * @brief manages balancing.
832  *
833  * Reads balancing order from database and balances the corresponding cells.
834  *
835  * @param n775_state state of the N775A driver
836  *
837  */
839  FAS_ASSERT(n775_state != NULL_PTR);
840 
841  N775_BalanceSetup(n775_state);
842 
844 
845  for (uint8_t m = 0u; m < BS_NR_OF_MODULES_PER_STRING; m++) {
846  uint8_t deviceAddress = m + 1u;
847  uint16_t balancingState = 0u;
848  for (uint16_t c = 0u; c < BS_NR_OF_CELL_BLOCKS_PER_MODULE; c++) {
849  if (n775_state->n775Data.balancingControl
850  ->balancingState[n775_state->currentString][c + (m * BS_NR_OF_CELL_BLOCKS_PER_MODULE)] != 0u) {
851  balancingState |= 1u << c;
852  }
853  }
854  /* All channels active --> 14 bits set to 1 --> 0x3FFF */
855  FAS_ASSERT(balancingState <= 0x3FFFu);
856  /* Enable channels, one written to a channels means balancing active */
857  N775_CommunicationWrite(deviceAddress, MC33775_BAL_CH_CFG_OFFSET, balancingState, n775_state->pSpiTxSequence);
858  }
859 }
860 
861 /**
862  * @brief gets the measurement initialization status.
863  *
864  * @param n775_state state of the N775A driver
865  *
866  * @return retval true if a first measurement cycle was made, false otherwise
867  *
868  */
870  bool retval = false;
871 
873  retval = n775_state->firstMeasurementMade;
875 
876  return retval;
877 }
878 
879 /**
880  * @brief sets the measurement initialization status.
881  *
882  * @param n775_state state of the N775A driver
883  *
884  */
887  n775_state->firstMeasurementMade = true;
889 }
890 
893 }
894 
895 /**
896  * @brief waits for a definite amount of time in ms.
897  *
898  * This function uses FreeRTOS. It blocks the tasks for
899  * the given amount of miliseconds.
900  *
901  * @param milliseconds time to wait in ms
902  *
903  */
904 void N775_waitTime(uint32_t milliseconds) {
905  uint32_t current_time = OS_GetTickCount();
906  /* Block task without possibility to wake up */
907  OS_DelayTaskUntil(&current_time, milliseconds);
908 }
909 
910 /*========== Externalized Static Function Implementations (Unit Test) =======*/
Headers for the driver for the general DMA module of monitoring ICs.
#define BS_NR_OF_CELL_BLOCKS_PER_MODULE
number of cells per module
#define BS_NR_OF_STRINGS
Number of parallel strings in the battery pack.
#define BS_NR_OF_TEMP_SENSORS_PER_MODULE
number of temperature sensors per battery module
#define BS_NR_OF_GPIOS_PER_MODULE
Number of GPIOs on the LTC IC.
#define BS_NR_OF_CELL_BLOCKS_PER_STRING
#define BS_NR_OF_MODULES_PER_STRING
number of modules in a string
#define BS_NR_OF_TEMP_SENSORS_PER_STRING
Database module header.
#define DATA_READ_DATA(...)
Definition: database.h:83
#define DATA_WRITE_DATA(...)
Definition: database.h:93
@ DATA_BLOCK_ID_BALANCING_CONTROL
Definition: database_cfg.h:80
@ DATA_BLOCK_ID_MIN_MAX
Definition: database_cfg.h:78
@ DATA_BLOCK_ID_CELL_TEMPERATURE_BASE
Definition: database_cfg.h:98
@ DATA_BLOCK_ID_OPEN_WIRE_BASE
Definition: database_cfg.h:84
@ DATA_BLOCK_ID_SLAVE_CONTROL
Definition: database_cfg.h:81
@ DATA_BLOCK_ID_CELL_VOLTAGE_BASE
Definition: database_cfg.h:97
@ DATA_BLOCK_ID_ALL_GPIO_VOLTAGES_BASE
Definition: database_cfg.h:85
@ DATA_BLOCK_ID_BALANCING_FEEDBACK_BASE
Definition: database_cfg.h:82
Diagnosis driver 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
Header for the driver for the IO module.
Headers for the driver for the MCU module.
N775_COMMUNICATION_STATUS_e N775_CommunicationReadMultiple(uint16_t deviceAddress, uint16_t numberOfItems, uint16_t responseLength, uint16_t registerAddress, uint16_t *pValues, N775_STATE_s *n775_state)
Read multiple values from specific registers in a specific device.
void N775_ResetMessageCounter(uint16_t deviceAddress, uint8_t string)
Reset the message counter for one or all devices.
void N775_CommunicationWrite(uint16_t deviceAddress, uint16_t registerAddress, uint16_t value, SPI_INTERFACE_CONFIG_s *pSpiInterface)
Write a value into a specific register in a specific device.
N775_COMMUNICATION_STATUS_e N775_CommunicationRead(uint16_t deviceAddress, uint16_t registerAddress, uint16_t *pValue, N775_STATE_s *n775_state)
Read a value from a specific register in a specific device.
enum N775_COMMUNICATION_STATUS N775_COMMUNICATION_STATUS_e
@ N775_COMMUNICATION_OK
@ N775_COMMUNICATION_ERROR_WRONG_CRC
@ N775_COMMUNICATION_ERROR_TIMEOUT
static DATA_BLOCK_SLAVE_CONTROL_s n775_slaveControl
Definition: nxp_mc33775a.c:88
void TEST_N775_SetFirstMeasurementCycleFinished(N775_STATE_s *n775_state)
Definition: nxp_mc33775a.c:891
static N775_ERRORTABLE_s n775_errorTable
Definition: nxp_mc33775a.c:92
void N775_ErrorHandling(N775_STATE_s *n775_state, N775_COMMUNICATION_STATUS_e returnedValue, uint8_t module)
handles error when doing measurements.
Definition: nxp_mc33775a.c:365
uint16_t n775_CrcAddItem(uint16_t remainder, uint16_t item)
Called to calculate the CRC of a message.
Definition: nxp_mc33775a.c:152
void N775_Meas(N775_STATE_s *n775_state)
trigger function for the N775 driver state machine.
Definition: nxp_mc33775a.c:251
N775_STATE_s n775_stateBase
Definition: nxp_mc33775a.c:96
static DATA_BLOCK_ALL_GPIO_VOLTAGES_s n775_allGpioVoltage
Definition: nxp_mc33775a.c:85
STD_RETURN_TYPE_e N775_SetMuxChannel(N775_STATE_s *n775_state)
sets mux channel.
Definition: nxp_mc33775a.c:692
static DATA_BLOCK_MIN_MAX_s n775_minMax
Definition: nxp_mc33775a.c:83
static DATA_BLOCK_CELL_TEMPERATURE_s n775_cellTemperature
Definition: nxp_mc33775a.c:82
void N775_IncrementStringSequence(N775_STATE_s *n775_state)
updates index in string sequence.
Definition: nxp_mc33775a.c:322
uint16_t n775_CalcCrc(const N775_MESSAGE_s *msg)
Calculate the CRC of a message.
Definition: nxp_mc33775a.c:179
static void N775_SetFirstMeasurementCycleFinished(N775_STATE_s *n775_state)
sets the measurement initialization status.
Definition: nxp_mc33775a.c:885
void N775_StartMeasurement(N775_STATE_s *n775_state)
starts the measurement.
Definition: nxp_mc33775a.c:513
static DATA_BLOCK_CELL_VOLTAGE_s n775_cellVoltage
Definition: nxp_mc33775a.c:81
void N775_BalanceControl(N775_STATE_s *n775_state)
manages balancing.
Definition: nxp_mc33775a.c:838
void N775_ResetMuxIndex(N775_STATE_s *n775_state)
resets index in mux sequence.
Definition: nxp_mc33775a.c:334
void N775_IncrementMuxIndex(N775_STATE_s *n775_state)
updates index in mux sequence.
Definition: nxp_mc33775a.c:345
static DATA_BLOCK_BALANCING_CONTROL_s n775_balancingControl
Definition: nxp_mc33775a.c:84
void N775_BalanceSetup(N775_STATE_s *n775_state)
setups balancing.
Definition: nxp_mc33775a.c:799
void N775_I2cInit(N775_STATE_s *n775_state)
init I2C for the N775 slaves.
Definition: nxp_mc33775a.c:493
void N775_CaptureMeasurement(N775_STATE_s *n775_state)
captures the measurement.
Definition: nxp_mc33775a.c:541
static N775_SUPPLY_CURRENT_s n775_supplyCurrent
Definition: nxp_mc33775a.c:91
static DATA_BLOCK_OPEN_WIRE_s n775_openwire
Definition: nxp_mc33775a.c:89
void N775_Init(N775_STATE_s *n775_state)
initializes the N775 driver.
Definition: nxp_mc33775a.c:394
static void N775_InitializeDatabase(N775_STATE_s *n775_state)
in the database, initializes the fields related to the N775 driver.
Definition: nxp_mc33775a.c:202
void N775_ResetStringSequence(N775_STATE_s *n775_state)
reset index in string sequence.
Definition: nxp_mc33775a.c:310
static DATA_BLOCK_BALANCING_FEEDBACK_s n775_balancingFeedback
Definition: nxp_mc33775a.c:86
STD_RETURN_TYPE_e N775_Enumerate(N775_STATE_s *n775_state)
enumerates the N775 slaves.
Definition: nxp_mc33775a.c:416
void N775_waitTime(uint32_t milliseconds)
waits for a definite amount of time in ms.
Definition: nxp_mc33775a.c:904
bool N775_IsFirstMeasurementCycleFinished(N775_STATE_s *n775_state)
gets the measurement initialization status.
Definition: nxp_mc33775a.c:869
Headers for the driver for the MC33775A monitoring chip.
N775_MUX_CH_CFG_s n775_muxSequence[N775_MUX_SEQUENCE_LENGTH]
int16_t N775_ConvertVoltagesToTemperatures(uint16_t adcVoltage_mV)
converts a raw voltage from multiplexer to a temperature value in deci °C.
#define N775_I2C_NR_BYTES_FOR_MUX_WRITE
#define N775_I2C_NR_BYTES_TO_SWITCH_TO_READ_FOR_UX_READ
#define N775_MEASUREMENT_CAPTURE_TIME_MS
#define N775_INVALID_REGISTER_VALUE
#define N775_I2C_DUMMY_BYTE
#define N775_CHECK_SUPPLY_CURRENT
#define N775_TIMEOUT_SWITCH
#define N775_TIMEOUT_TO_SLEEP_10MS
#define N775_CHECK_MUX_STATE
#define N775_DEFAULT_CHAIN_ADDRESS
#define N775_I2C_READ
#define N775_MUXED_TEMP_GPIO_POSITION
#define N775_MEASUREMENT_READY_TIME_MS
#define N775_MUX_SEQUENCE_LENGTH
#define N775_FLAG_READY_TIMEOUT
#define N775_I2C_WRITE
#define N775_ADG728_ADDRESS_UPPERBITS
#define N775_BROADCAST_ADDRESS
#define N775_USE_MUX_FOR_TEMP
#define N775_PRE_BALANCING_TIMER
#define N775_BALPAUSELEN_10US
#define N775_GLOBAL_BALANCING_TIMER
#define N775_WAKEUP_TIME_MS
#define N775_TIME_AFTER_MEASUREMENT_START_MS
#define N775_ALL_CHANNEL_BALANCING_TIMER
Declaration of the OS wrapper interface.
void OS_DelayTaskUntil(uint32_t *pPreviousWakeTime, uint32_t milliseconds)
Delay a task until a specified time.
Definition: os_freertos.c:143
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
uint32_t OS_GetTickCount(void)
Returns OS based system tick value.
Definition: os_freertos.c:139
Headers for the driver for the SPI module.
SPI_INTERFACE_CONFIG_s spi_nxp775InterfaceTx[BS_NR_OF_STRINGS]
Definition: spi_cfg.c:193
SPI_INTERFACE_CONFIG_s spi_nxp775InterfaceRx[BS_NR_OF_STRINGS]
Definition: spi_cfg.c:204
uint16_t gpioVoltages_mV[BS_NR_OF_STRINGS][BS_NR_OF_MODULES_PER_STRING *BS_NR_OF_GPIOS_PER_MODULE]
Definition: database_cfg.h:318
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:315
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:247
uint8_t balancingState[BS_NR_OF_STRINGS][BS_NR_OF_CELL_BLOCKS_PER_STRING]
Definition: database_cfg.h:252
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:282
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:146
int16_t cellTemperature_ddegC[BS_NR_OF_STRINGS][BS_NR_OF_TEMP_SENSORS_PER_STRING]
Definition: database_cfg.h:148
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:129
uint32_t moduleVoltage_mV[BS_NR_OF_STRINGS][BS_NR_OF_MODULES_PER_STRING]
Definition: database_cfg.h:137
int16_t cellVoltage_mV[BS_NR_OF_STRINGS][BS_NR_OF_CELL_BLOCKS_PER_STRING]
Definition: database_cfg.h:132
DATA_BLOCK_ID_e uniqueId
Definition: database_cfg.h:119
int16_t minimumTemperature_ddegC[BS_NR_OF_STRINGS]
Definition: database_cfg.h:172
uint16_t nrSensorMinimumTemperature[BS_NR_OF_STRINGS]
Definition: database_cfg.h:174
uint16_t nrModuleMinimumTemperature[BS_NR_OF_STRINGS]
Definition: database_cfg.h:173
uint16_t nrModuleMaximumTemperature[BS_NR_OF_STRINGS]
Definition: database_cfg.h:176
int16_t maximumTemperature_ddegC[BS_NR_OF_STRINGS]
Definition: database_cfg.h:175
uint16_t nrSensorMaximumTemperature[BS_NR_OF_STRINGS]
Definition: database_cfg.h:177
uint16_t nrCellMaximumCellVoltage[BS_NR_OF_STRINGS]
Definition: database_cfg.h:169
uint16_t nrCellMinimumCellVoltage[BS_NR_OF_STRINGS]
Definition: database_cfg.h:167
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:159
uint16_t nrModuleMinimumCellVoltage[BS_NR_OF_STRINGS]
Definition: database_cfg.h:166
uint16_t nrModuleMaximumCellVoltage[BS_NR_OF_STRINGS]
Definition: database_cfg.h:168
int16_t maximumCellVoltage_mV[BS_NR_OF_STRINGS]
Definition: database_cfg.h:164
int16_t minimumCellVoltage_mV[BS_NR_OF_STRINGS]
Definition: database_cfg.h:162
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:302
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:263
N775_ERRORTABLE_s * errorTable
DATA_BLOCK_BALANCING_CONTROL_s * balancingControl
uint64_t uid[BS_NR_OF_STRINGS][BS_NR_OF_MODULES_PER_STRING]
DATA_BLOCK_CELL_TEMPERATURE_s * cellTemperature
DATA_BLOCK_ALL_GPIO_VOLTAGES_s * allGpioVoltage
N775_SUPPLY_CURRENT_s * supplyCurrent
DATA_BLOCK_MIN_MAX_s * minMax
DATA_BLOCK_CELL_VOLTAGE_s * cellVoltage
bool mux3IsOK[BS_NR_OF_STRINGS][BS_NR_OF_MODULES_PER_STRING]
bool communicationOk[BS_NR_OF_STRINGS][BS_NR_OF_MODULES_PER_STRING]
bool noCommunicationTimeout[BS_NR_OF_STRINGS][BS_NR_OF_MODULES_PER_STRING]
bool mux2IsOK[BS_NR_OF_STRINGS][BS_NR_OF_MODULES_PER_STRING]
bool mux0IsOk[BS_NR_OF_STRINGS][BS_NR_OF_MODULES_PER_STRING]
bool mux1IsOK[BS_NR_OF_STRINGS][BS_NR_OF_MODULES_PER_STRING]
bool crcIsValid[BS_NR_OF_STRINGS][BS_NR_OF_MODULES_PER_STRING]
SPI_INTERFACE_CONFIG_s * pSpiRxSequenceStart
SPI_INTERFACE_CONFIG_s * pSpiTxSequenceStart
N775_MUX_CH_CFG_s * pMuxSequence[BS_NR_OF_STRINGS]
SPI_INTERFACE_CONFIG_s * pSpiTxSequence
SPI_INTERFACE_CONFIG_s * pSpiRxSequence
N775_DATAPTR_s n775Data
uint8_t currentMux[BS_NR_OF_STRINGS]
N775_MUX_CH_CFG_s * pMuxSequenceStart[BS_NR_OF_STRINGS]
uint16_t current[BS_NR_OF_STRINGS][BS_NR_OF_MODULES_PER_STRING]