foxBMS  1.6.0
The foxBMS Battery Management System API Documentation
mxm_1785x_tools.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 mxm_1785x_tools.c
44  * @author foxBMS Team
45  * @date 2020-07-15 (date of creation)
46  * @updated 2023-10-12 (date of last update)
47  * @version v1.6.0
48  * @ingroup DRIVERS
49  * @prefix MXM
50  *
51  * @brief This is a collection of helper functions for the MAX1785x ICs
52  *
53  * @details This collection of helper functions for the MAX1785x ICs helps to
54  * calculate the lsb and msb for register values and similar tasks.
55  *
56  */
57 
58 /*========== Includes =======================================================*/
59 #include "general.h"
60 
61 #include "mxm_1785x_tools.h"
62 
63 #include "fassert.h"
64 #include "fstd_types.h"
65 #include "mxm_register_map.h"
66 
67 #include <stdint.h>
68 
69 /*========== Macros and Definitions =========================================*/
70 /** length of a byte */
71 #define MXM_TOOLS_LENGTH_BYTE (8u)
72 
73 /*========== Static Constant and Variable Definitions =======================*/
74 
75 /*========== Extern Constant and Variable Definitions =======================*/
76 
77 /*========== Static Function Prototypes =====================================*/
78 /**
79  * @brief Find Position of first set bit in bitmask
80  * @details Searches a bitmask starting from the lowest bit and returns the
81  * position of the first set bit.
82  * @param[in] bitmask bitmask that should be searched
83  * @return position of first set bit
84  */
85 static uint8_t MXM_FirstSetBit(uint16_t bitmask);
86 
87 /*========== Static Function Implementations ================================*/
88 static uint8_t MXM_FirstSetBit(uint16_t bitmask) {
89  /* AXIVION Routine Generic-MissingParameterAssert: bitmask: parameter accepts whole range */
90  uint8_t retval = 0;
91  while (((bitmask >> retval) & 1u) == 0u) {
92  retval++;
93  /* exit if every entry is zero */
94  if (retval >= 16u) {
95  break;
96  }
97  }
98  return retval;
99 }
100 
101 /*========== Extern Function Implementations ================================*/
103  /* AXIVION Disable Style Generic-NoMagicNumbers: This test function uses magic numbers to test predefined values. */
104 
105  /* bitmasks containing only zeros should return first bit set 16 */
107 
109 
111 
113 
114  /* AXIVION Enable Style Generic-NoMagicNumbers: */
115 
116  return STD_OK;
117 }
118 
119 extern void MXM_Convert(
120  uint8_t lsb,
121  uint8_t msb,
122  uint16_t *pTarget,
123  MXM_CONVERSION_TYPE_e convType,
124  uint32_t fullScaleReference_mV) {
125  FAS_ASSERT(pTarget != NULL_PTR);
126  /* AXIVION Routine Generic-MissingParameterAssert: lsb: parameter accepts whole range */
127  /* AXIVION Routine Generic-MissingParameterAssert: msb: parameter accepts whole range */
128  /* AXIVION Routine Generic-MissingParameterAssert: convType: parameter accepts whole range */
129  /* AXIVION Routine Generic-MissingParameterAssert: fullScaleReference_mV: parameter accepts whole range */
130  uint16_t temporaryVoltage = 0;
131  MXM_ExtractValueFromRegister(lsb, msb, MXM_REG_ADC_14BIT_VALUE, &temporaryVoltage);
132 
133  temporaryVoltage = temporaryVoltage + (uint16_t)1u;
134  const uint32_t scaledVoltageUnipolar_mV = (temporaryVoltage * fullScaleReference_mV) / 0x3FFFu;
135 
136  switch (convType) {
138  /* not yet supported */
140  break;
143  if (scaledVoltageUnipolar_mV > (uint16_t)UINT16_MAX) {
144  *pTarget = UINT16_MAX;
145  } else {
146  *pTarget = (uint16_t)scaledVoltageUnipolar_mV;
147  }
148  break;
149  default:
150  /* we should not be here */
152  break;
153  }
154 }
155 
157  /* AXIVION Disable Style Generic-NoMagicNumbers: This test function uses magic numbers to test predefined values. */
158 
160 
161  /* low scale */
162  uint8_t msb = 0x00u;
163  uint8_t lsb = 0x00u;
164  uint16_t voltage = 1;
165  MXM_Convert(lsb, msb, &voltage, conversionType, 5000);
166  FAS_ASSERT(voltage == 0u);
167 
168  /* half scale */
169  msb = 0x80u;
170  lsb = 0x00u;
171  voltage = 0;
172  MXM_Convert(lsb, msb, &voltage, conversionType, 5000);
173  FAS_ASSERT(voltage == 2500u);
174 
175  /* full scale */
176  msb = 0xFFu;
177  lsb = 0xFCu;
178  voltage = 0;
179  MXM_Convert(lsb, msb, &voltage, conversionType, 5000);
180  FAS_ASSERT(voltage == 5000u);
181 
182  /* AXIVION Enable Style Generic-NoMagicNumbers: */
183 
184  return STD_OK;
185 }
186 
187 extern void MXM_ExtractValueFromRegister(uint8_t lsb, uint8_t msb, MXM_REG_BM bitmask, uint16_t *pValue) {
188  /* input sanitation */
189  FAS_ASSERT(pValue != NULL_PTR);
190  /* AXIVION Routine Generic-MissingParameterAssert: lsb: parameter accepts whole range */
191  /* AXIVION Routine Generic-MissingParameterAssert: msb: parameter accepts whole range */
192  /* AXIVION Routine Generic-MissingParameterAssert: bitmask: parameter accepts whole range */
193 
194  /* find lowest bit that is 1 in bitmask */
195  uint8_t start = MXM_FirstSetBit(bitmask);
196 
197  /* apply bitmask to MSB */
198  uint16_t msbBitmask = (bitmask & MXM_BM_MSB);
199  uint8_t msbMasked = msb & ((uint8_t)(msbBitmask >> MXM_TOOLS_LENGTH_BYTE));
200 
201  /* shift LSB into right position if lsb is used */
202  if (start < MXM_TOOLS_LENGTH_BYTE) {
203  /* apply bitmask to LSB */
204  uint8_t lsbMasked = lsb & ((uint8_t)(bitmask & MXM_BM_LSB));
205  *pValue = ((uint16_t)lsbMasked >> start);
206  /* add MSB at right position */
207  *pValue = (((uint16_t)msbMasked << (MXM_TOOLS_LENGTH_BYTE - start)) | *pValue);
208  } else if (start == MXM_TOOLS_LENGTH_BYTE) {
209  *pValue = (uint16_t)msbMasked;
210  } else {
211  *pValue = ((uint16_t)msbMasked >> (start - MXM_TOOLS_LENGTH_BYTE));
212  }
213 }
214 
216  /* AXIVION Disable Style Generic-NoMagicNumbers: This test function uses magic numbers to test predefined values. */
217  uint8_t lsb = 0x31u;
218  uint8_t msb = 0x85u;
219  uint16_t value = 0x00u;
221  FAS_ASSERT(value == 0x853u);
222 
224  FAS_ASSERT(value == 0x01u);
225 
226  lsb = 0xFCu;
227  msb = 0xFFu;
228  value = 0x00u;
230  FAS_ASSERT(value == 0x3FFFu);
231 
232  lsb = 0xFEu;
233  msb = 0x7Fu;
234  value = 0x00u;
236  FAS_ASSERT(value == 0x1FFFu);
237 
238  /* AXIVION Enable Style Generic-NoMagicNumbers: */
239 
240  return STD_OK;
241 }
242 
243 extern void MXM_Unipolar14BitInto16Bit(uint16_t inputValue, uint8_t *lsb, uint8_t *msb) {
244  FAS_ASSERT(lsb != NULL_PTR);
245  FAS_ASSERT(msb != NULL_PTR);
246  /* AXIVION Routine Generic-MissingParameterAssert: inputValue: parameter accepts whole range */
247 
248  uint16_t workingCopy = inputValue;
249  /* left shift into 16bit position */
250  workingCopy = workingCopy << 2u;
251 
252  /* bitmask LSB */
253  *lsb = (uint8_t)(workingCopy & MXM_BM_LSB);
254  /* shift MSB into lower byte (workingCopy is 16bit) */
255  *msb = (uint8_t)(workingCopy >> MXM_TOOLS_LENGTH_BYTE);
256 }
257 
258 extern uint16_t MXM_VoltageIntoUnipolar14Bit(uint16_t voltage_mV, uint16_t fullscaleReference_mV) {
259  /* AXIVION Routine Generic-MissingParameterAssert: voltage_mV: parameter accepts whole range */
260  /* AXIVION Routine Generic-MissingParameterAssert: fullscaleReference_mV: parameter accepts whole range */
261 
262  uint32_t temporaryVoltage = voltage_mV;
263  /* multiply by the 14bit fullscale */
264  temporaryVoltage = temporaryVoltage * 0x3FFFu;
265  /* return divided by fullscale_reference */
266  return (uint16_t)(temporaryVoltage / fullscaleReference_mV);
267 }
268 
270  const uint16_t moduleNumber,
271  uint8_t *pStringNumber,
272  uint16_t *pModuleNumberInString) {
273  FAS_ASSERT(pStringNumber != NULL_PTR);
274  FAS_ASSERT(pModuleNumberInString != NULL_PTR);
275  /* the module number cannot be higher than the highest module in the daisy-chain */
276  FAS_ASSERT(moduleNumber < MXM_MAXIMUM_NR_OF_MODULES);
277  /* the module number cannot be higher than number of maximum modules in the string */
279 
280  /* calculate string number */
281  *pStringNumber = (uint8_t)(moduleNumber / BS_NR_OF_MODULES_PER_STRING);
282  FAS_ASSERT(*pStringNumber <= BS_NR_OF_STRINGS);
283  /* calculate module number and handle edge-case BS_NR_OF_MODULES_PER_STRING == 1 */
284  if (1u == BS_NR_OF_MODULES_PER_STRING) {
285  *pModuleNumberInString = 0u;
286  } else {
287  *pModuleNumberInString = moduleNumber % BS_NR_OF_MODULES_PER_STRING;
288  }
289  FAS_ASSERT(*pModuleNumberInString <= BS_NR_OF_MODULES_PER_STRING);
290 }
291 
292 /*========== Externalized Static Function Implementations (Unit Test) =======*/
293 #ifdef UNITY_UNIT_TEST
294 #endif
#define BS_NR_OF_STRINGS
Number of parallel strings in the battery pack.
#define BS_NR_OF_MODULES_PER_STRING
number of modules in a string
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
Definition of foxBMS standard types.
STD_RETURN_TYPE_e
Definition: fstd_types.h:82
@ STD_OK
Definition: fstd_types.h:83
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:77
General macros and definitions for the whole platform.
#define GEN_MUST_CHECK_RETURN
Allows functions to generate warnings in GCC for unused returns.
Definition: general.h:87
#define MXM_BM_LSB
Monitoring Register LSB.
#define MXM_BM_MSB
Monitoring Register MSB.
#define MXM_BM_NULL
Monitoring Register Null byte.
#define MXM_REG_VERSION_VER
Monitoring Register Version/Silicon Version.
#define MXM_REG_VERSION_MOD
Monitoring Register Version/Model.
#define MXM_REG_ADC_14BIT_VALUE
Monitoring Register 14bit ADC value.
static uint8_t MXM_FirstSetBit(uint16_t bitmask)
Find Position of first set bit in bitmask.
void MXM_Unipolar14BitInto16Bit(uint16_t inputValue, uint8_t *lsb, uint8_t *msb)
convert a unipolar 14bit-value and shifts it into the 16bit-format
void MXM_ConvertModuleToString(const uint16_t moduleNumber, uint8_t *pStringNumber, uint16_t *pModuleNumberInString)
Get the string and module number from a global module number.
STD_RETURN_TYPE_e GEN_MUST_CHECK_RETURN MXM_ConvertTest(void)
Test the MXM_Convert()-function.
STD_RETURN_TYPE_e GEN_MUST_CHECK_RETURN MXM_ExtractValueFromRegisterTest(void)
Test MXM_ExtractValueFromRegister().
#define MXM_TOOLS_LENGTH_BYTE
uint16_t MXM_VoltageIntoUnipolar14Bit(uint16_t voltage_mV, uint16_t fullscaleReference_mV)
convert a voltage value into a unipolar 14bit value
void MXM_Convert(uint8_t lsb, uint8_t msb, uint16_t *pTarget, MXM_CONVERSION_TYPE_e convType, uint32_t fullScaleReference_mV)
Convert a measurement value to a voltage value.
STD_RETURN_TYPE_e GEN_MUST_CHECK_RETURN MXM_FirstSetBitTest(void)
Test MXM_FirstSetBit().
void MXM_ExtractValueFromRegister(uint8_t lsb, uint8_t msb, MXM_REG_BM bitmask, uint16_t *pValue)
Extract a value from a single register.
This is a collection of helper functions for the MAX1785x ICs.
MXM_CONVERSION_TYPE_e
@ MXM_CONVERSION_BIPOLAR
@ MXM_CONVERSION_UNIPOLAR
@ MXM_CONVERSION_BLOCK_VOLTAGE
#define MXM_MAXIMUM_NR_OF_MODULES
Maximum number of modules.
Register map of the MAX1785x monitoring IC.
uint16_t MXM_REG_BM
Type for register access for monitoring ICs.