foxBMS  1.2.1
The foxBMS Battery Management System API Documentation
mxm_1785x_tools.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 mxm_1785x_tools.c
44  * @author foxBMS Team
45  * @date 2020-07-15 (date of creation)
46  * @updated 2021-12-06 (date of last update)
47  * @ingroup DRIVERS
48  * @prefix MXM
49  *
50  * @brief This is a collection of helper functions for the MAX1785x ICs
51  *
52  * @details This collection of helper functions for the MAX1785x ICs helps to
53  * calculate the lsb and msb for register values and similar tasks.
54  *
55  */
56 
57 /*========== Includes =======================================================*/
58 #include "mxm_1785x_tools.h"
59 
60 #include "mxm_register_map.h"
61 
62 /*========== Macros and Definitions =========================================*/
63 /** length of a byte */
64 #define MXM_TOOLS_LENGTH_BYTE (8u)
65 
66 /*========== Static Constant and Variable Definitions =======================*/
67 
68 /*========== Extern Constant and Variable Definitions =======================*/
69 
70 /*========== Static Function Prototypes =====================================*/
71 /**
72  * @brief Find Position of first set bit in bitmask
73  * @details Searches a bitmask starting from the lowest bit and returns the
74  * position of the first set bit.
75  * @param[in] bitmask bitmask that should be searched
76  * @return position of first set bit
77  */
78 static uint8_t MXM_FirstSetBit(uint16_t bitmask);
79 
80 /*========== Static Function Implementations ================================*/
81 static uint8_t MXM_FirstSetBit(uint16_t bitmask) {
82  uint8_t retval = 0;
83  while (((bitmask >> retval) & 1u) == 0u) {
84  retval++;
85  /* exit if every entry is zero */
86  if (retval >= 16u) {
87  break;
88  }
89  }
90  return retval;
91 }
92 
93 /*========== Extern Function Implementations ================================*/
95  /* AXIVION Disable Style Generic-NoMagicNumbers: This test function uses magic numbers to test predefined values. */
96 
97  /* bitmasks containing only zeros should return first bit set 16 */
99 
101 
103 
105 
106  /* AXIVION Enable Style Generic-NoMagicNumbers: */
107 
108  return STD_OK;
109 }
110 
111 extern void MXM_Convert(
112  uint8_t lsb,
113  uint8_t msb,
114  uint16_t *pTarget,
115  MXM_CONVERSION_TYPE_e convType,
116  uint32_t fullScaleReference_mV) {
117  FAS_ASSERT(pTarget != NULL_PTR);
118  uint16_t temporaryVoltage = 0;
119  MXM_ExtractValueFromRegister(lsb, msb, MXM_REG_ADC_14BIT_VALUE, &temporaryVoltage);
120 
121  temporaryVoltage = temporaryVoltage + (uint16_t)1u;
122  const uint32_t scaledVoltageUnipolar_mV = (temporaryVoltage * fullScaleReference_mV) / 0x3FFFu;
123 
124  switch (convType) {
126  /* not yet supported */
128  break;
131  if (scaledVoltageUnipolar_mV > (uint16_t)UINT16_MAX) {
132  *pTarget = UINT16_MAX;
133  } else {
134  *pTarget = (uint16_t)scaledVoltageUnipolar_mV;
135  }
136  break;
137  default:
138  /* we should not be here */
140  break;
141  }
142 }
143 
145  /* AXIVION Disable Style Generic-NoMagicNumbers: This test function uses magic numbers to test predefined values. */
146 
148 
149  /* low scale */
150  uint8_t msb = 0x00u;
151  uint8_t lsb = 0x00u;
152  uint16_t voltage = 1;
153  MXM_Convert(lsb, msb, &voltage, conversionType, 5000);
154  FAS_ASSERT(voltage == 0u);
155 
156  /* half scale */
157  msb = 0x80u;
158  lsb = 0x00u;
159  voltage = 0;
160  MXM_Convert(lsb, msb, &voltage, conversionType, 5000);
161  FAS_ASSERT(voltage == 2500u);
162 
163  /* full scale */
164  msb = 0xFFu;
165  lsb = 0xFCu;
166  voltage = 0;
167  MXM_Convert(lsb, msb, &voltage, conversionType, 5000);
168  FAS_ASSERT(voltage == 5000u);
169 
170  /* AXIVION Enable Style Generic-NoMagicNumbers: */
171 
172  return STD_OK;
173 }
174 
175 extern void MXM_ExtractValueFromRegister(uint8_t lsb, uint8_t msb, MXM_REG_BM bitmask, uint16_t *pValue) {
176  /* input sanitation */
177  FAS_ASSERT(pValue != NULL_PTR);
178 
179  /* find lowest bit that is 1 in bitmask */
180  uint8_t start = MXM_FirstSetBit(bitmask);
181 
182  /* apply bitmask to MSB */
183  uint16_t msbBitmask = (bitmask & MXM_BM_MSB);
184  uint8_t msbMasked = msb & ((uint8_t)(msbBitmask >> MXM_TOOLS_LENGTH_BYTE));
185 
186  /* shift LSB into right position if lsb is used */
187  if (start < MXM_TOOLS_LENGTH_BYTE) {
188  /* apply bitmask to LSB */
189  uint8_t lsbMasked = lsb & ((uint8_t)(bitmask & MXM_BM_LSB));
190  *pValue = ((uint16_t)lsbMasked >> start);
191  /* add MSB at right position */
192  *pValue = (((uint16_t)msbMasked << (MXM_TOOLS_LENGTH_BYTE - start)) | *pValue);
193  } else if (start == MXM_TOOLS_LENGTH_BYTE) {
194  *pValue = (uint16_t)msbMasked;
195  } else {
196  *pValue = ((uint16_t)msbMasked >> (start - MXM_TOOLS_LENGTH_BYTE));
197  }
198 }
199 
201  /* AXIVION Disable Style Generic-NoMagicNumbers: This test function uses magic numbers to test predefined values. */
202  uint8_t lsb = 0x31u;
203  uint8_t msb = 0x85u;
204  uint16_t value = 0x00u;
206  FAS_ASSERT(value == 0x853u);
207 
209  FAS_ASSERT(value == 0x01u);
210 
211  lsb = 0xFCu;
212  msb = 0xFFu;
213  value = 0x00u;
215  FAS_ASSERT(value == 0x3FFFu);
216 
217  lsb = 0xFEu;
218  msb = 0x7Fu;
219  value = 0x00u;
221  FAS_ASSERT(value == 0x1FFFu);
222 
223  /* AXIVION Enable Style Generic-NoMagicNumbers: */
224 
225  return STD_OK;
226 }
227 
228 extern void MXM_Unipolar14BitInto16Bit(uint16_t inputValue, uint8_t *lsb, uint8_t *msb) {
229  FAS_ASSERT(lsb != NULL_PTR);
230  FAS_ASSERT(msb != NULL_PTR);
231  uint16_t workingCopy = inputValue;
232  /* left shift into 16bit position */
233  workingCopy = workingCopy << 2u;
234 
235  /* bitmask LSB */
236  *lsb = (uint8_t)(workingCopy & MXM_BM_LSB);
237  /* shift MSB into lower byte (workingCopy is 16bit) */
238  *msb = (uint8_t)(workingCopy >> MXM_TOOLS_LENGTH_BYTE);
239 }
240 
241 extern uint16_t MXM_VoltageIntoUnipolar14Bit(uint16_t voltage_mV, uint16_t fullscaleReference_mV) {
242  uint32_t temporaryVoltage = voltage_mV;
243  /* multiply by the 14bit fullscale */
244  temporaryVoltage = temporaryVoltage * 0x3FFFu;
245  /* return divided by fullscale_reference */
246  return (uint16_t)(temporaryVoltage / fullscaleReference_mV);
247 }
248 
250  const uint16_t moduleNumber,
251  uint8_t *pStringNumber,
252  uint16_t *pModuleNumberInString) {
253  FAS_ASSERT(pStringNumber != NULL_PTR);
254  FAS_ASSERT(pModuleNumberInString != NULL_PTR);
255  /* the module number cannot be higher than the highest module in the daisy-chain */
256  FAS_ASSERT(moduleNumber < MXM_MAXIMUM_NR_OF_MODULES);
257  /* the module number cannot be higher than number of maximum modules in the string */
258  FAS_ASSERT(moduleNumber < (BS_NR_OF_STRINGS * BS_NR_OF_MODULES));
259 
260  /* calculate string number */
261  *pStringNumber = (uint8_t)(moduleNumber / BS_NR_OF_MODULES);
262  FAS_ASSERT(*pStringNumber <= BS_NR_OF_STRINGS);
263  /* calculate module number and handle edge-case BS_NR_OF_MODULES == 1 */
264  if (1u == BS_NR_OF_MODULES) {
265  *pModuleNumberInString = 0u;
266  } else {
267  *pModuleNumberInString = moduleNumber % BS_NR_OF_MODULES;
268  }
269  FAS_ASSERT(*pModuleNumberInString <= BS_NR_OF_MODULES);
270 }
271 
272 /*========== Externalized Static Function Implementations (Unit Test) =======*/
#define BS_NR_OF_STRINGS
#define BS_NR_OF_MODULES
number of modules in battery pack
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:239
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:110
@ STD_OK
Definition: fstd_types.h:81
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:75
enum STD_RETURN_TYPE STD_RETURN_TYPE_e
#define must_check_return
Allows functions to generate warnings in GCC for unused returns.
Definition: general.h:101
#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 must_check_return MXM_ConvertTest(void)
Test the MXM_Convert()-function.
#define MXM_TOOLS_LENGTH_BYTE
STD_RETURN_TYPE_e must_check_return MXM_FirstSetBitTest(void)
Test MXM_FirstSetBit().
uint16_t MXM_VoltageIntoUnipolar14Bit(uint16_t voltage_mV, uint16_t fullscaleReference_mV)
convert a voltage value into a unipolar 14bit value
STD_RETURN_TYPE_e must_check_return MXM_ExtractValueFromRegisterTest(void)
Test MXM_ExtractValueFromRegister().
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.
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.