foxBMS  1.4.1
The foxBMS Battery Management System API Documentation
mxm_registry.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 mxm_registry.c
44  * @author foxBMS Team
45  * @date 2020-07-16 (date of creation)
46  * @updated 2022-10-27 (date of last update)
47  * @version v1.4.1
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 "foxmath.h"
61 
62 /*========== Macros and Definitions =========================================*/
63 
64 /** default value for status and fmea registers (for initialization) */
65 #define MXM_MON_REGISTRY_STATUS_FMEA_DEFAULT (0xFFFFu)
66 
67 /** shift distance for one byte */
68 #define MXM_REGISTRY_SHIFT_ONE_BYTE (8u)
69 
70 /*========== Static Constant and Variable Definitions =======================*/
71 
72 /*========== Extern Constant and Variable Definitions =======================*/
73 
74 /*========== Static Function Prototypes =====================================*/
75 
76 /*========== Static Function Implementations ================================*/
77 
78 /*========== Extern Function Implementations ================================*/
80  FAS_ASSERT(pState != NULL_PTR);
81  for (uint8_t i = 0; i < MXM_MAXIMUM_NR_OF_MODULES; i++) {
82  MXM_REGISTRY_ENTRY_s *entry = &pState->registry[i];
83  entry->connected = false;
84  entry->deviceAddress = 0u;
85  entry->deviceID = 0u;
86  entry->model = MXM_MODEL_ID_NONE;
93  }
94 }
95 
97  FAS_ASSERT(pState != NULL_PTR);
98  /* AXIVION Routine Generic-MissingParameterAssert: numberOfDevices: parameter accepts whole range */
99 
100  STD_RETURN_TYPE_e retval = STD_OK;
101  if (numberOfDevices > MXM_MAXIMUM_NR_OF_MODULES) {
102  retval = STD_NOT_OK;
103  } else {
104  for (uint8_t i = 0; i < numberOfDevices; i++) {
105  pState->registry[i].connected = true;
106  pState->registry[i].deviceAddress = HELLOALL_START_SEED + i;
107  pState->highest5xDevice = HELLOALL_START_SEED + i;
108  }
109  }
110 
111  return retval;
112 }
113 
114 /* AXIVION Next Codeline Style MisraC2012-8.7: this function is API of the registry and should therefore be extern */
116  FAS_ASSERT(kpkState != NULL_PTR);
117  /* return highest connected device */
118  return kpkState->highest5xDevice;
119 }
120 
123  uint8_t rxBufferLength,
124  MXM_REG_NAME_e type) {
125  FAS_ASSERT(pState != NULL_PTR);
126  FAS_ASSERT(rxBufferLength <= MXM_RX_BUFFER_LENGTH);
127  /* only ID1 or ID2 are valid */
128  FAS_ASSERT((type == MXM_REG_ID1) || (type == MXM_REG_ID2));
129 
130  /* find highest connected device */
131  const uint8_t highestConnectedDevice =
133 
134  const uint8_t startBytes = 2u;
135 
136  for (uint8_t i = 0; i <= highestConnectedDevice; i++) {
137  const uint8_t bufferPosition = startBytes + (i * 2u);
138  MXM_REGISTRY_ENTRY_s *currentDevice = &pState->registry[highestConnectedDevice - i];
139  FAS_ASSERT((bufferPosition + 1u) <= rxBufferLength);
140  uint16_t id = 0;
142  pState->rxBuffer[bufferPosition], pState->rxBuffer[bufferPosition + 1u], MXM_BM_WHOLE_REG, &id);
143  if (type == MXM_REG_ID1) {
144  currentDevice->deviceID = id;
145  } else {
146  /* intended condition: type is MXM_REG_ID2 */
147  currentDevice->deviceID = ((uint32_t)id << 16u) | currentDevice->deviceID;
148  }
149  }
150 }
151 
152 extern void MXM_MonRegistryParseVersionIntoDevices(MXM_MONITORING_INSTANCE_s *pState, uint8_t rxBufferLength) {
153  FAS_ASSERT(pState != NULL_PTR);
154  FAS_ASSERT(pState->rxBuffer != NULL_PTR);
155  FAS_ASSERT(rxBufferLength <= MXM_RX_BUFFER_LENGTH);
156 
157  /* find highest connected device */
158  const uint8_t highestConnectedDevice =
160 
161  for (uint8_t i = 0; i <= highestConnectedDevice; i++) {
162  const uint8_t startBytes = 2u;
163  const uint8_t bufferPosition = startBytes + (i * 2u);
164  MXM_REGISTRY_ENTRY_s *currentDevice = &pState->registry[highestConnectedDevice - i];
165  FAS_ASSERT((bufferPosition + 1u) <= rxBufferLength);
166  uint16_t model = 0;
168  pState->rxBuffer[bufferPosition], pState->rxBuffer[bufferPosition + 1u], MXM_REG_VERSION_MOD, &model);
169  if (model >= (uint16_t)MXM_MODEL_ID_invalid) {
170  currentDevice->model = MXM_MODEL_ID_invalid;
171  } else if (
172  (model != (uint16_t)MXM_MODEL_ID_MAX17852) && (model != (uint16_t)MXM_MODEL_ID_MAX17853) &&
173  (model != (uint16_t)MXM_MODEL_ID_MAX17854)) {
174  currentDevice->model = MXM_MODEL_ID_invalid;
175  } else {
176  /* AXIVION Next Codeline Style MisraC2012-10.5: All invalid values have been cleared. */
177  currentDevice->model = (MXM_MODEL_ID_e)model;
178  }
179 
180  uint16_t version = 0;
182  pState->rxBuffer[bufferPosition], pState->rxBuffer[bufferPosition + 1u], MXM_REG_VERSION_VER, &version);
183  if (version >= (uint16_t)MXM_SILICON_VERSION_INVALID) {
184  currentDevice->siliconVersion = MXM_SILICON_VERSION_INVALID;
185  } else {
186  /* AXIVION Next Codeline Style MisraC2012-10.5: All invalid values have been cleared. */
187  currentDevice->siliconVersion = (MXM_SILICON_VERSION_e)version;
188  }
189  }
190 }
191 
192 extern void MXM_MonRegistryParseStatusFmeaIntoDevices(MXM_MONITORING_INSTANCE_s *pState, uint8_t rxBufferLength) {
193  FAS_ASSERT(pState != NULL_PTR);
194  FAS_ASSERT(pState->rxBuffer != NULL_PTR);
195  FAS_ASSERT(rxBufferLength <= MXM_RX_BUFFER_LENGTH);
196 
197  /* find highest connected device */
198  const uint8_t highestConnectedDevice =
200 
201  /* detect which register has been read */
202  const uint8_t currentRegister = pState->rxBuffer[1u];
203 
204  for (uint8_t i = 0; i <= highestConnectedDevice; i++) {
205  const uint8_t startBytes = 2u;
206  const uint8_t bufferPosition = startBytes + (i * 2u);
207  MXM_REGISTRY_ENTRY_s *currentDevice = &pState->registry[highestConnectedDevice - i];
208  FAS_ASSERT((bufferPosition + 1u) <= rxBufferLength);
209  uint16_t registerValue = 0u;
211  pState->rxBuffer[bufferPosition], pState->rxBuffer[bufferPosition + 1u], MXM_BM_WHOLE_REG, &registerValue);
212 
213  switch (currentRegister) {
214  case (uint8_t)MXM_REG_STATUS1:
215  currentDevice->registerStatus1 = registerValue;
216  break;
217  case (uint8_t)MXM_REG_STATUS2:
218  currentDevice->registerStatus2 = registerValue;
219  break;
220  case (uint8_t)MXM_REG_STATUS3:
221  currentDevice->registerStatus3 = registerValue;
222  break;
223  case (uint8_t)MXM_REG_FMEA1:
224  currentDevice->registerFmea1 = registerValue;
225  break;
226  case (uint8_t)MXM_REG_FMEA2:
227  currentDevice->registerFmea2 = registerValue;
228  break;
229  case (uint8_t)MXM_REG_BALSTAT:
230  currentDevice->registerBalstat = registerValue;
231  break;
232  default:
233  /* unknown register, just discard */
234  break;
235  }
236  }
237 }
238 
239 extern bool MXM_CheckIfADeviceHasBeenReset(const MXM_MONITORING_INSTANCE_s *const kpkState) {
240  FAS_ASSERT(kpkState != NULL_PTR);
241 
242  /* find highest connected device */
243  const uint8_t highestConnectedDevice =
245 
246  bool deviceReset = false;
247 
248  for (uint8_t i = 0; i <= highestConnectedDevice; i++) {
249  const uint16_t status1 = kpkState->registry[i].registerStatus1;
250  const uint8_t lsb = (uint8_t)(status1 & MXM_BM_LSB);
251  const uint8_t msb = (uint8_t)((status1 & MXM_BM_MSB) >> MXM_REGISTRY_SHIFT_ONE_BYTE);
252  uint16_t alertReset = 0u;
254  if (alertReset == 1u) {
255  deviceReset = true;
256  }
257  }
258 
259  return deviceReset;
260 }
261 
262 extern bool MXM_CheckIfADeviceIsConnected(const MXM_MONITORING_INSTANCE_s *const kpkState, uint8_t device) {
263  FAS_ASSERT(kpkState != NULL_PTR);
265  return kpkState->registry[device].connected;
266 }
267 
268 /*========== Externalized Static Function Implementations (Unit Test) =======*/
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:252
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:138
math library for often used math functions
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
#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:262
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:121
void MXM_MonRegistryInit(MXM_MONITORING_INSTANCE_s *pState)
Initialize monitoring registry.
Definition: mxm_registry.c:79
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:96
#define MXM_MON_REGISTRY_STATUS_FMEA_DEFAULT
Definition: mxm_registry.c:65
uint8_t MXM_MonRegistryGetHighestConnected5XDevice(const MXM_MONITORING_INSTANCE_s *const kpkState)
Parse number of highest connected device from monitoring- register.
Definition: mxm_registry.c:115
void MXM_MonRegistryParseStatusFmeaIntoDevices(MXM_MONITORING_INSTANCE_s *pState, uint8_t rxBufferLength)
Parse STATUS or FMEA into the registry.
Definition: mxm_registry.c:192
void MXM_MonRegistryParseVersionIntoDevices(MXM_MONITORING_INSTANCE_s *pState, uint8_t rxBufferLength)
Parse Version into the registry.
Definition: mxm_registry.c:152
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:239
#define MXM_REGISTRY_SHIFT_ONE_BYTE
Definition: mxm_registry.c:68
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