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