foxBMS  1.6.0
The foxBMS Battery Management System API Documentation
mxm_registry.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_registry.c
44  * @author foxBMS Team
45  * @date 2020-07-16 (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 Functions in order to have a registry of monitoring ICs
52  *
53  * @details Monitoring registry stores information about the connected ICs.
54  *
55  */
56 
57 /*========== Includes =======================================================*/
58 #include "mxm_registry.h"
59 
60 #include "fassert.h"
61 #include "foxmath.h"
62 #include "fstd_types.h"
63 
64 #include <stdint.h>
65 
66 /*========== Macros and Definitions =========================================*/
67 
68 /** default value for status and fmea registers (for initialization) */
69 #define MXM_MON_REGISTRY_STATUS_FMEA_DEFAULT (0xFFFFu)
70 
71 /** shift distance for one byte */
72 #define MXM_REGISTRY_SHIFT_ONE_BYTE (8u)
73 
74 /*========== Static Constant and Variable Definitions =======================*/
75 
76 /*========== Extern Constant and Variable Definitions =======================*/
77 
78 /*========== Static Function Prototypes =====================================*/
79 
80 /*========== Static Function Implementations ================================*/
81 
82 /*========== Extern Function Implementations ================================*/
84  FAS_ASSERT(pState != NULL_PTR);
85  for (uint8_t i = 0; i < MXM_MAXIMUM_NR_OF_MODULES; i++) {
86  MXM_REGISTRY_ENTRY_s *entry = &pState->registry[i];
87  entry->connected = false;
88  entry->deviceAddress = 0u;
89  entry->deviceID = 0u;
90  entry->model = MXM_MODEL_ID_NONE;
97  }
98 }
99 
101  FAS_ASSERT(pState != NULL_PTR);
102  /* AXIVION Routine Generic-MissingParameterAssert: numberOfDevices: parameter accepts whole range */
103 
104  STD_RETURN_TYPE_e retval = STD_OK;
105  if (numberOfDevices > MXM_MAXIMUM_NR_OF_MODULES) {
106  retval = STD_NOT_OK;
107  } else {
108  for (uint8_t i = 0; i < numberOfDevices; i++) {
109  pState->registry[i].connected = true;
110  pState->registry[i].deviceAddress = HELLOALL_START_SEED + i;
111  pState->highest5xDevice = HELLOALL_START_SEED + i;
112  }
113  }
114 
115  return retval;
116 }
117 
118 /* AXIVION Next Codeline Style MisraC2012-8.7: this function is API of the registry and should therefore be extern */
120  FAS_ASSERT(kpkState != NULL_PTR);
121  /* return highest connected device */
122  return kpkState->highest5xDevice;
123 }
124 
127  uint8_t rxBufferLength,
128  MXM_REG_NAME_e type) {
129  FAS_ASSERT(pState != NULL_PTR);
130  FAS_ASSERT(rxBufferLength <= MXM_RX_BUFFER_LENGTH);
131  /* only ID1 or ID2 are valid */
132  FAS_ASSERT((type == MXM_REG_ID1) || (type == MXM_REG_ID2));
133 
134  /* find highest connected device */
135  const uint8_t highestConnectedDevice =
137 
138  const uint8_t startBytes = 2u;
139 
140  for (uint8_t i = 0; i <= highestConnectedDevice; i++) {
141  const uint8_t bufferPosition = startBytes + (i * 2u);
142  MXM_REGISTRY_ENTRY_s *currentDevice = &pState->registry[highestConnectedDevice - i];
143  FAS_ASSERT((bufferPosition + 1u) <= rxBufferLength);
144  uint16_t id = 0;
146  pState->rxBuffer[bufferPosition], pState->rxBuffer[bufferPosition + 1u], MXM_BM_WHOLE_REG, &id);
147  if (type == MXM_REG_ID1) {
148  currentDevice->deviceID = id;
149  } else {
150  /* intended condition: type is MXM_REG_ID2 */
151  currentDevice->deviceID = ((uint32_t)id << 16u) | currentDevice->deviceID;
152  }
153  }
154 }
155 
156 extern void MXM_MonRegistryParseVersionIntoDevices(MXM_MONITORING_INSTANCE_s *pState, uint8_t rxBufferLength) {
157  FAS_ASSERT(pState != NULL_PTR);
158  FAS_ASSERT(pState->rxBuffer != NULL_PTR);
159  FAS_ASSERT(rxBufferLength <= MXM_RX_BUFFER_LENGTH);
160 
161  /* find highest connected device */
162  const uint8_t highestConnectedDevice =
164 
165  for (uint8_t i = 0; i <= highestConnectedDevice; i++) {
166  const uint8_t startBytes = 2u;
167  const uint8_t bufferPosition = startBytes + (i * 2u);
168  MXM_REGISTRY_ENTRY_s *currentDevice = &pState->registry[highestConnectedDevice - i];
169  FAS_ASSERT((bufferPosition + 1u) <= rxBufferLength);
170  uint16_t model = 0;
172  pState->rxBuffer[bufferPosition], pState->rxBuffer[bufferPosition + 1u], MXM_REG_VERSION_MOD, &model);
173  if (model >= (uint16_t)MXM_MODEL_ID_invalid) {
174  currentDevice->model = MXM_MODEL_ID_invalid;
175  } else if (
176  (model != (uint16_t)MXM_MODEL_ID_MAX17852) && (model != (uint16_t)MXM_MODEL_ID_MAX17853) &&
177  (model != (uint16_t)MXM_MODEL_ID_MAX17854)) {
178  currentDevice->model = MXM_MODEL_ID_invalid;
179  } else {
180  /* AXIVION Next Codeline Style MisraC2012-10.5: All invalid values have been cleared. */
181  currentDevice->model = (MXM_MODEL_ID_e)model;
182  }
183 
184  uint16_t version = 0;
186  pState->rxBuffer[bufferPosition], pState->rxBuffer[bufferPosition + 1u], MXM_REG_VERSION_VER, &version);
187  if (version >= (uint16_t)MXM_SILICON_VERSION_INVALID) {
188  currentDevice->siliconVersion = MXM_SILICON_VERSION_INVALID;
189  } else {
190  /* AXIVION Next Codeline Style MisraC2012-10.5: All invalid values have been cleared. */
191  currentDevice->siliconVersion = (MXM_SILICON_VERSION_e)version;
192  }
193  }
194 }
195 
196 extern void MXM_MonRegistryParseStatusFmeaIntoDevices(MXM_MONITORING_INSTANCE_s *pState, uint8_t rxBufferLength) {
197  FAS_ASSERT(pState != NULL_PTR);
198  FAS_ASSERT(pState->rxBuffer != NULL_PTR);
199  FAS_ASSERT(rxBufferLength <= MXM_RX_BUFFER_LENGTH);
200 
201  /* find highest connected device */
202  const uint8_t highestConnectedDevice =
204 
205  /* detect which register has been read */
206  const uint8_t currentRegister = pState->rxBuffer[1u];
207 
208  for (uint8_t i = 0; i <= highestConnectedDevice; i++) {
209  const uint8_t startBytes = 2u;
210  const uint8_t bufferPosition = startBytes + (i * 2u);
211  MXM_REGISTRY_ENTRY_s *currentDevice = &pState->registry[highestConnectedDevice - i];
212  FAS_ASSERT((bufferPosition + 1u) <= rxBufferLength);
213  uint16_t registerValue = 0u;
215  pState->rxBuffer[bufferPosition], pState->rxBuffer[bufferPosition + 1u], MXM_BM_WHOLE_REG, &registerValue);
216 
217  switch (currentRegister) {
218  case (uint8_t)MXM_REG_STATUS1:
219  currentDevice->registerStatus1 = registerValue;
220  break;
221  case (uint8_t)MXM_REG_STATUS2:
222  currentDevice->registerStatus2 = registerValue;
223  break;
224  case (uint8_t)MXM_REG_STATUS3:
225  currentDevice->registerStatus3 = registerValue;
226  break;
227  case (uint8_t)MXM_REG_FMEA1:
228  currentDevice->registerFmea1 = registerValue;
229  break;
230  case (uint8_t)MXM_REG_FMEA2:
231  currentDevice->registerFmea2 = registerValue;
232  break;
233  case (uint8_t)MXM_REG_BALSTAT:
234  currentDevice->registerBalstat = registerValue;
235  break;
236  default:
237  /* unknown register, just discard */
238  break;
239  }
240  }
241 }
242 
243 extern bool MXM_CheckIfADeviceHasBeenReset(const MXM_MONITORING_INSTANCE_s *const kpkState) {
244  FAS_ASSERT(kpkState != NULL_PTR);
245 
246  /* find highest connected device */
247  const uint8_t highestConnectedDevice =
249 
250  bool deviceReset = false;
251 
252  for (uint8_t i = 0; i <= highestConnectedDevice; i++) {
253  const uint16_t status1 = kpkState->registry[i].registerStatus1;
254  const uint8_t lsb = (uint8_t)(status1 & MXM_BM_LSB);
255  const uint8_t msb = (uint8_t)((status1 & MXM_BM_MSB) >> MXM_REGISTRY_SHIFT_ONE_BYTE);
256  uint16_t alertReset = 0u;
258  if (alertReset == 1u) {
259  deviceReset = true;
260  }
261  }
262 
263  return deviceReset;
264 }
265 
266 extern bool MXM_CheckIfADeviceIsConnected(const MXM_MONITORING_INSTANCE_s *const kpkState, uint8_t device) {
267  FAS_ASSERT(kpkState != NULL_PTR);
269  return kpkState->registry[device].connected;
270 }
271 
272 /*========== Externalized Static Function Implementations (Unit Test) =======*/
273 #ifdef UNITY_UNIT_TEST
274 #endif
Assert macro implementation.
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:255
uint8_t MATH_MinimumOfTwoUint8_t(const uint8_t value1, const uint8_t value2)
Returns the minimum of the passed uint8_t values.
Definition: foxmath.c:136
math library for often used math functions
Definition of foxBMS standard types.
STD_RETURN_TYPE_e
Definition: fstd_types.h:82
@ STD_NOT_OK
Definition: fstd_types.h:84
@ STD_OK
Definition: fstd_types.h:83
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:77
#define MXM_BM_LSB
Monitoring Register LSB.
#define MXM_BM_WHOLE_REG
All bits of monitoring register.
#define MXM_BM_MSB
Monitoring Register MSB.
#define MXM_REG_VERSION_VER
Monitoring Register Version/Silicon Version.
#define MXM_REG_VERSION_MOD
Monitoring Register Version/Model.
#define MXM_REG_STATUS1_ALRTRST
ALRTRST bit in STATUS1.
void MXM_ExtractValueFromRegister(uint8_t lsb, uint8_t msb, MXM_REG_BM bitmask, uint16_t *pValue)
Extract a value from a single register.
#define MXM_RX_BUFFER_LENGTH
Length of RX buffer.
MXM_SILICON_VERSION_e
@ MXM_SILICON_VERSION_INVALID
@ MXM_SILICON_VERSION_0
MXM_MODEL_ID_e
Type of monitoring device.
@ MXM_MODEL_ID_MAX17853
@ MXM_MODEL_ID_MAX17852
@ MXM_MODEL_ID_MAX17854
@ MXM_MODEL_ID_NONE
@ MXM_MODEL_ID_invalid
#define MXM_MAXIMUM_NR_OF_MODULES
Maximum number of modules.
#define HELLOALL_START_SEED
MXM_REG_NAME_e
MAX1785x register names.
@ MXM_REG_STATUS1
@ MXM_REG_STATUS3
@ MXM_REG_STATUS2
@ MXM_REG_BALSTAT
@ MXM_REG_ID1
@ MXM_REG_FMEA1
@ MXM_REG_ID2
@ MXM_REG_FMEA2
bool MXM_CheckIfADeviceIsConnected(const MXM_MONITORING_INSTANCE_s *const kpkState, uint8_t device)
check if a device is connected
Definition: mxm_registry.c:266
void MXM_MonRegistryParseIdIntoDevices(MXM_MONITORING_INSTANCE_s *pState, uint8_t rxBufferLength, MXM_REG_NAME_e type)
Parse ID (1 or 2) into the registry.
Definition: mxm_registry.c:125
void MXM_MonRegistryInit(MXM_MONITORING_INSTANCE_s *pState)
Initialize monitoring registry.
Definition: mxm_registry.c:83
STD_RETURN_TYPE_e MXM_MonRegistryConnectDevices(MXM_MONITORING_INSTANCE_s *pState, uint8_t numberOfDevices)
Mark devices as connected in the registry and set the address.
Definition: mxm_registry.c:100
#define MXM_MON_REGISTRY_STATUS_FMEA_DEFAULT
Definition: mxm_registry.c:69
uint8_t MXM_MonRegistryGetHighestConnected5XDevice(const MXM_MONITORING_INSTANCE_s *const kpkState)
Parse number of highest connected device from monitoring- register.
Definition: mxm_registry.c:119
void MXM_MonRegistryParseStatusFmeaIntoDevices(MXM_MONITORING_INSTANCE_s *pState, uint8_t rxBufferLength)
Parse STATUS or FMEA into the registry.
Definition: mxm_registry.c:196
void MXM_MonRegistryParseVersionIntoDevices(MXM_MONITORING_INSTANCE_s *pState, uint8_t rxBufferLength)
Parse Version into the registry.
Definition: mxm_registry.c:156
bool MXM_CheckIfADeviceHasBeenReset(const MXM_MONITORING_INSTANCE_s *const kpkState)
check if one of the devices in the registry has the ALRTRST bit set
Definition: mxm_registry.c:243
#define MXM_REGISTRY_SHIFT_ONE_BYTE
Definition: mxm_registry.c:72
Functions in order to have a registry of monitoring ICs.
uint8_t rxBuffer[MXM_RX_BUFFER_LENGTH]
MXM_REGISTRY_ENTRY_s registry[MXM_MAXIMUM_NR_OF_MODULES]
MXM_SILICON_VERSION_e siliconVersion
uint16_t registerStatus2
uint16_t registerStatus3
uint32_t deviceID
uint16_t registerFmea2
uint8_t deviceAddress
MXM_MODEL_ID_e model
uint16_t registerStatus1
uint16_t registerFmea1
bool connected