foxBMS  1.6.0
The foxBMS Battery Management System API Documentation
adi_ades1830_gpio_voltages.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2023, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice, this
12  * list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  *
18  * 3. Neither the name of the copyright holder nor the names of its
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * We kindly request you to use one or more of the following phrases to refer to
34  * foxBMS in your hardware, software, documentation or advertising materials:
35  *
36  * - ″This product uses parts of foxBMS®″
37  * - ″This product includes parts of foxBMS®″
38  * - ″This product is derived from foxBMS®″
39  *
40  */
41 
42 /**
43  * @file adi_ades1830_gpio_voltages.c
44  * @author foxBMS Team
45  * @date 2019-08-27 (date of creation)
46  * @updated 2023-10-12 (date of last update)
47  * @version v1.6.0
48  * @ingroup SOME_GROUP
49  * @prefix ADI
50  *
51  * @brief Implementation of some software
52  *
53  */
54 
55 /*========== Includes =======================================================*/
56 /* clang-format off */
58 /* clang-format on */
59 
60 #include "adi_ades183x_cfg.h"
61 
62 #include "adi_ades183x_buffers.h"
63 #include "adi_ades183x_commands.h"
65 #include "adi_ades183x_defs.h"
66 #include "adi_ades183x_helpers.h"
67 #include "adi_ades183x_voltages.h"
68 #include "fassert.h"
69 
70 #include <math.h>
71 #include <stdbool.h>
72 #include <stdint.h>
73 
74 /*========== Macros and Definitions =========================================*/
75 
76 /*========== Static Constant and Variable Definitions =======================*/
77 
78 /*========== Extern Constant and Variable Definitions =======================*/
79 
80 /*========== Static Function Prototypes =====================================*/
81 /**
82  * @brief Saves the GPIO voltage values read from the daisy-chain.
83  * @details There are up to 5 registers to read _(A, B, C, D, E) to get all
84  * GPIO voltages.
85  * This function is called to store the result from the transmission
86  * buffer to the appropriate location in the driver.
87  * @param adiState state of the ADI driver
88  * @param data receive buffer
89  * @param registerSet auxiliary register that was read (voltage register
90  * A, B, C or D).
91  * @param storeLocation location where read data has to be stored
92  */
94  ADI_STATE_s *adiState,
95  uint8_t *data,
96  uint8_t registerSet,
97  ADI_AUXILIARY_STORE_LOCATION_e storeLocation);
98 
99 /*========== Static Function Implementations ================================*/
100 /* RequirementId: D7.1 V0R4 FUN-2.10.01.02 */
102  ADI_STATE_s *adiState,
103  uint8_t *data,
104  uint8_t registerSet,
105  ADI_AUXILIARY_STORE_LOCATION_e storeLocation) {
106  FAS_ASSERT(adiState != NULL_PTR);
107  FAS_ASSERT(data != NULL_PTR);
108  FAS_ASSERT(
109  (registerSet == ADI_AUXILIARY_RESULT_REGISTER_SET_A) || (registerSet == ADI_AUXILIARY_RESULT_REGISTER_SET_B) ||
110  (registerSet == ADI_AUXILIARY_RESULT_REGISTER_SET_C) || (registerSet == ADI_AUXILIARY_RESULT_REGISTER_SET_D) ||
111  (registerSet == ADI_AUXILIARY_RESULT_REGISTER_SET_E));
112  FAS_ASSERT(
113  (storeLocation == ADI_AUXILIARY_VOLTAGE) || (storeLocation == ADI_REDUNDANT_AUXILIARY_VOLTAGE) ||
114  (storeLocation == ADI_AUXILIARY_VOLTAGE_OPEN_WIRE));
115 
116  uint16_t cellOffset = 0u;
117  uint16_t voltageIndex = 0u;
118  uint16_t rawValue = 0u;
119  int16_t signedValue = 0;
120  float_t floatVoltage = 0.0f;
121  int16_t voltage = 0;
122  uint16_t bufferLSB = 0u;
123  uint16_t bufferMSB = 0u;
124  uint8_t numberOfVoltagesInRegister = 0u;
125  uint8_t voltageStartNumber = 0u;
126  DATA_BLOCK_ALL_GPIO_VOLTAGES_s *pGpioVoltageTable = NULL_PTR;
127 
128  switch (storeLocation) {
130  pGpioVoltageTable = adiState->data.allGpioVoltages;
131  break;
133  pGpioVoltageTable = adiState->data.allGpioVoltagesRedundant;
134  break;
136  pGpioVoltageTable = adiState->data.allGpioVoltageOpenWire;
137  break;
138  default: /* LCOV_EXCL_LINE */
139  FAS_ASSERT(FAS_TRAP); /* LCOV_EXCL_LINE */
140  break; /* LCOV_EXCL_LINE */
141  }
142 
143  /* Default: 3 GPIO voltages in AUX registers */
144  numberOfVoltagesInRegister = ADI_MAX_NUMBER_OF_GPIO_VOLTAGES_IN_REGISTER;
145 
146  switch (registerSet) {
148  /* RDAUXA command -> auxiliary register group A */
149  cellOffset = ADI_VOLTAGE_00_02_OFFSET;
150  break;
152  /* RDAUXB command -> auxiliary register group B */
153  cellOffset = ADI_VOLTAGE_03_05_OFFSET;
154  break;
156  /* RDAUXC command -> auxiliary register group C */
157  cellOffset = ADI_VOLTAGE_06_08_OFFSET;
158  break;
160  /* RDAUXD command -> auxiliary register group D */
161  cellOffset = ADI_VOLTAGE_09_11_OFFSET;
162  numberOfVoltagesInRegister = ADI_NUMBER_OF_GPIO_VOLTAGES_IN_REGISTER_D;
163  break;
164  default: /* LCOV_EXCL_LINE */
165  FAS_ASSERT(FAS_TRAP); /* LCOV_EXCL_LINE */
166  break; /* LCOV_EXCL_LINE */
167  }
168 
169  for (uint16_t m = 0u; m < ADI_N_ADI; m++) {
170  /* parse voltages contained in one register */
171  for (uint16_t gpio = voltageStartNumber; gpio < numberOfVoltagesInRegister; gpio++) {
172  voltageIndex = gpio + cellOffset;
173  if (voltageIndex < BS_NR_OF_GPIOS_PER_MODULE) {
174  bufferMSB = (uint16_t)(data
176  (m * ADI_MAX_REGISTER_SIZE_IN_BYTES) + 1u]);
177  bufferLSB =
178  (uint16_t)(data[(ADI_RAW_VOLTAGE_SIZE_IN_BYTES * gpio) + (m * ADI_MAX_REGISTER_SIZE_IN_BYTES)]);
179  rawValue = bufferLSB | (bufferMSB << ADI_BYTE_SHIFT);
180  signedValue = (int16_t)rawValue;
181  floatVoltage = ((float_t)signedValue * ADI_VOLTAGE_CONVERSION_FACTOR * ADI_VOLTAGE_CONVERSION_UNIT) +
183  voltage = (int16_t)floatVoltage; /* Unit mV */
184 
185  /* RequirementId: D7.1 V0R4 SIF-4.40.02.01 */
186  /* Check that register does not contain cleared value */
187  if (rawValue != ADI_REGISTER_CLEARED_VALUE) {
188  adiState->data.errorTable->auxiliaryRegisterContentIsNotStuck[adiState->currentString][m] = true;
189  /* Check PEC for every IC in the daisy-chain */
190  if (adiState->data.errorTable->crcIsOk[adiState->currentString][m] == true) {
191  pGpioVoltageTable->gpioVoltages_mV[adiState->currentString]
192  [voltageIndex + (m * BS_NR_OF_GPIOS_PER_MODULE)] = voltage;
193  }
194  } else {
195  adiState->data.errorTable->auxiliaryRegisterContentIsNotStuck[adiState->currentString][m] = false;
196  }
197  }
198  }
199  }
200 }
201 
202 /*========== Extern Function Implementations ================================*/
204  ADI_STATE_s *adiState,
205  ADI_AUXILIARY_REGISTER_TYPE_e registerType,
206  ADI_AUXILIARY_STORE_LOCATION_e storeLocation) {
207  FAS_ASSERT(adiState != NULL_PTR);
208  FAS_ASSERT((registerType == ADI_AUXILIARY_REGISTER) || (registerType == ADI_REDUNDANT_AUXILIARY_REGISTER));
209  FAS_ASSERT(
210  (storeLocation == ADI_AUXILIARY_VOLTAGE) || (storeLocation == ADI_REDUNDANT_AUXILIARY_VOLTAGE) ||
211  (storeLocation == ADI_AUXILIARY_VOLTAGE_OPEN_WIRE));
212  uint16_t registerA[ADI_COMMAND_DEFINITION_LENGTH] = {0};
213  uint16_t registerB[ADI_COMMAND_DEFINITION_LENGTH] = {0};
214  uint16_t registerC[ADI_COMMAND_DEFINITION_LENGTH] = {0};
215  uint16_t registerD[ADI_COMMAND_DEFINITION_LENGTH] = {0};
216  uint16_t registerE[ADI_COMMAND_DEFINITION_LENGTH] = {0};
217 
218  switch (registerType) {
225  break;
231  break;
232  default: /* LCOV_EXCL_LINE */
233  FAS_ASSERT(FAS_TRAP); /* LCOV_EXCL_LINE */
234  break; /* LCOV_EXCL_LINE */
235  }
236 
237  ADI_CopyCommandBits(registerA, adi_command);
240 
241  ADI_CopyCommandBits(registerB, adi_command);
244 
245  ADI_CopyCommandBits(registerC, adi_command);
248 
249  ADI_CopyCommandBits(registerD, adi_command);
252 }
253 
254 /*========== Externalized Static Function Implementations (Unit Test) =======*/
255 #ifdef UNITY_UNIT_TEST
256 extern void TEST_ADI_SaveRxToGpioVoltageBuffer(
257  ADI_STATE_s *adiState,
258  uint8_t *data,
259  uint8_t registerSet,
260  ADI_AUXILIARY_STORE_LOCATION_e storeLocation) {
261  ADI_SaveRxToGpioVoltageBuffer(adiState, data, registerSet, storeLocation);
262 }
263 #endif
static void ADI_SaveRxToGpioVoltageBuffer(ADI_STATE_s *adiState, uint8_t *data, uint8_t registerSet, ADI_AUXILIARY_STORE_LOCATION_e storeLocation)
Saves the GPIO voltage values read from the daisy-chain.
void ADI_GetGpioVoltages(ADI_STATE_s *adiState, ADI_AUXILIARY_REGISTER_TYPE_e registerType, ADI_AUXILIARY_STORE_LOCATION_e storeLocation)
Stores GPIO voltages.
uint16_t adi_command[ADI_COMMAND_DEFINITION_LENGTH]
uint8_t adi_dataReceive[BS_NR_OF_MODULES_PER_STRING *ADI_MAX_REGISTER_SIZE_IN_BYTES]
Header for the buffers used by the driver for the ADI analog front-end.
Header for the configuration for the ADI analog front-end.
const uint16_t adi_cmdRdauxb[ADI_COMMAND_DEFINITION_LENGTH]
const uint16_t adi_cmdRdauxa[ADI_COMMAND_DEFINITION_LENGTH]
const uint16_t adi_cmdRdauxe[ADI_COMMAND_DEFINITION_LENGTH]
const uint16_t adi_cmdRdraxc[ADI_COMMAND_DEFINITION_LENGTH]
const uint16_t adi_cmdRdraxa[ADI_COMMAND_DEFINITION_LENGTH]
const uint16_t adi_cmdRdraxd[ADI_COMMAND_DEFINITION_LENGTH]
const uint16_t adi_cmdRdauxc[ADI_COMMAND_DEFINITION_LENGTH]
const uint16_t adi_cmdRdraxb[ADI_COMMAND_DEFINITION_LENGTH]
const uint16_t adi_cmdRdauxd[ADI_COMMAND_DEFINITION_LENGTH]
Header file of some software.
Header file of some software.
Headers for the driver for the ades183x analog front-end.
#define ADI_AUXILIARY_RESULT_REGISTER_SET_C
#define ADI_BYTE_SHIFT
#define ADI_MAX_NUMBER_OF_GPIO_VOLTAGES_IN_REGISTER
#define ADI_VOLTAGE_CONVERSION_FACTOR
#define ADI_RAW_VOLTAGE_SIZE_IN_BYTES
#define ADI_VOLTAGE_CONVERSION_UNIT
#define ADI_N_ADI
#define ADI_VOLTAGE_06_08_OFFSET
#define ADI_AUXILIARY_RESULT_REGISTER_SET_D
#define ADI_MAX_REGISTER_SIZE_IN_BYTES
#define ADI_VOLTAGE_00_02_OFFSET
#define ADI_AUXILIARY_RESULT_REGISTER_SET_E
#define ADI_REGISTER_CLEARED_VALUE
#define ADI_VOLTAGE_CONVERSION_OFFSET
#define ADI_VOLTAGE_03_05_OFFSET
#define ADI_AUXILIARY_RESULT_REGISTER_SET_A
#define ADI_NUMBER_OF_GPIO_VOLTAGES_IN_REGISTER_D
ADI_AUXILIARY_REGISTER_TYPE_e
@ ADI_REDUNDANT_AUXILIARY_REGISTER
@ ADI_AUXILIARY_REGISTER
#define ADI_VOLTAGE_09_11_OFFSET
ADI_AUXILIARY_STORE_LOCATION_e
@ ADI_AUXILIARY_VOLTAGE
@ ADI_AUXILIARY_VOLTAGE_OPEN_WIRE
@ ADI_REDUNDANT_AUXILIARY_VOLTAGE
#define ADI_COMMAND_DEFINITION_LENGTH
#define ADI_AUXILIARY_RESULT_REGISTER_SET_B
Header file of some software.
void ADI_ReadRegister(uint16_t *registerToRead, uint8_t *data, ADI_STATE_s *adiState)
send command to the ades183x daisy-chain to read a register.
void ADI_CopyCommandBits(const uint16_t *sourceCommand, uint16_t *destinationCommand)
copy command bits in variables.
Headers for the diagnostic driver for the ADI analog front-end.
Header file of some software.
#define BS_NR_OF_GPIOS_PER_MODULE
Defines the number of GPIOs.
Assert macro implementation.
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:255
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:129
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:77
DATA_BLOCK_ALL_GPIO_VOLTAGES_s * allGpioVoltagesRedundant
DATA_BLOCK_ALL_GPIO_VOLTAGES_s * allGpioVoltages
DATA_BLOCK_ALL_GPIO_VOLTAGES_s * allGpioVoltageOpenWire
ADI_ERROR_TABLE_s * errorTable
bool crcIsOk[BS_NR_OF_STRINGS][ADI_N_ADI]
bool auxiliaryRegisterContentIsNotStuck[BS_NR_OF_STRINGS][ADI_N_ADI]
int16_t gpioVoltages_mV[BS_NR_OF_STRINGS][BS_NR_OF_MODULES_PER_STRING *BS_NR_OF_GPIOS_PER_MODULE]
Definition: database_cfg.h:325