foxBMS  1.6.0
The foxBMS Battery Management System API Documentation
fram.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 fram.c
44  * @author foxBMS Team
45  * @date 2020-03-05 (date of creation)
46  * @updated 2023-10-12 (date of last update)
47  * @version v1.6.0
48  * @ingroup DRIVERS
49  * @prefix FRAM
50  *
51  * @brief Driver for the FRAM module
52  *
53  *
54  */
55 
56 /*========== Includes =======================================================*/
57 #include "fram.h"
58 
59 #include "version_cfg.h"
60 
61 #include "crc.h"
62 #include "diag.h"
63 #include "fassert.h"
64 #include "fstd_types.h"
65 #include "io.h"
66 #include "mcu.h"
67 #include "spi.h"
68 
69 #include <stdint.h>
70 
71 /*========== Macros and Definitions =========================================*/
72 
73 /** delay in &micro;s after writing the FRAM */
74 #define FRAM_DELAY_AFTER_WRITE_ENABLE_US (5u)
75 
76 /** control commands for the FRAM */
77 /**@{*/
78 #define FRAM_WRITECOMMAND (0x02u)
79 #define FRAM_READCOMMAND (0x03u)
80 #define FRAM_WRITEENABLECOMMAND (0x06u)
81 /**@}*/
82 
83 /** maximal memory address of the FRAM */
84 #define FRAM_MAX_ADDRESS (0x3FFFFu)
85 
86 /*========== Static Constant and Variable Definitions =======================*/
87 
88 /*========== Extern Constant and Variable Definitions =======================*/
89 
90 /*========== Static Function Prototypes =====================================*/
91 
92 /*========== Static Function Implementations ================================*/
93 
94 /*========== Extern Function Implementations ================================*/
95 
96 extern void FRAM_Initialize(void) {
97  uint32_t address = 0u;
98 
99  /* Reset error flag at startup */
101  /* find address of all variables in FRAM by parsing length of data*/
102  for (uint16_t i = 0u; i < FRAM_BLOCK_MAX; i++) {
103  (fram_base_header[i]).address = address;
104  address += (fram_base_header[i]).datalength + FRAM_CRC_HEADER_SIZE;
105  }
106 
107  /* ASSERT that size of variables does not exceed FRAM size */
108  FAS_ASSERT(!(address > FRAM_MAX_ADDRESS));
109 
110  /* Read FRAM version struct - Set CRC error flag if this fails */
113  }
114 }
115 
117  STD_RETURN_TYPE_e retVal = STD_OK;
118 
119  /* Reset FRAM version struct information */
124 
125  for (uint16_t i = 0u; i < FRAM_BLOCK_MAX; i++) {
127  retVal = STD_OK;
128  }
129  }
130  return retVal;
131 }
132 
134  FAS_ASSERT(blockId < FRAM_BLOCK_MAX);
135 
136  uint16_t read = 0u;
137  uint64_t crc = 0u;
139 
140  /* FRAM must use SW Chip Select configuration*/
142 
143  uint32_t address = (fram_base_header[blockId]).address;
144  uint32_t size = (fram_base_header[blockId]).datalength;
145  uint8_t *pWrite = (uint8_t *)(fram_base_header[blockId].blockptr);
146 
147  STD_RETURN_TYPE_e crcRetVal = CRC_CalculateCrc(&crc, pWrite, size);
148 
149  if (crcRetVal == STD_OK) {
151 
152  if (spiRetVal == STD_OK) {
153  /* send write enable command */
155  uint16_t write = FRAM_WRITEENABLECOMMAND;
156  SPI_FramTransmitReceiveData(&spi_framInterface, &write, &read, 1u);
159 
160  /* send data to write */
161  /* set chip select low to start transmission */
163 
164  /* send write command */
165  write = FRAM_WRITECOMMAND;
166  SPI_FramTransmitReceiveData(&spi_framInterface, &write, &read, 1u);
167 
168  /* send upper part of address */
169  write = (address & 0x3F0000u) >> 16u;
170  SPI_FramTransmitReceiveData(&spi_framInterface, &write, &read, 1u);
171 
172  /* send middle part of address */
173  write = (address & 0xFF00u) >> 8u;
174  SPI_FramTransmitReceiveData(&spi_framInterface, &write, &read, 1u);
175 
176  /* send lower part of address */
177  write = address & 0xFFu;
178  SPI_FramTransmitReceiveData(&spi_framInterface, &write, &read, 1u);
179 
180  /* send CRC */
181  pWrite = (uint8_t *)(&crc);
182  for (uint8_t i = 0u; i < FRAM_CRC_HEADER_SIZE; i++) {
183  write = (uint16_t)(*pWrite);
184  SPI_FramTransmitReceiveData(&spi_framInterface, &write, &read, 1u);
185  pWrite++;
186  }
187 
188  pWrite = (uint8_t *)(fram_base_header[blockId].blockptr);
189 
190  /* send data */
191  while (size > 0u) {
192  write = (uint16_t)(*pWrite);
193  SPI_FramTransmitReceiveData(&spi_framInterface, &write, &read, 1u);
194  pWrite++;
195  size--;
196  }
197 
198  /* set chip select high to start transmission */
200 
202  } else {
203  retVal = FRAM_ACCESS_SPI_BUSY;
204  }
205  } else {
206  retVal = FRAM_ACCESS_CRC_BUSY;
207  }
208  return retVal;
209 }
210 
212  FAS_ASSERT(blockId < FRAM_BLOCK_MAX);
213 
214  uint16_t read = 0u;
216 
217  /* FRAM must use SW Chip Select configuration*/
219 
221 
222  if (spiRetVal == STD_OK) {
223  uint32_t address = (fram_base_header[blockId]).address;
224  uint32_t size = (fram_base_header[blockId]).datalength;
225 
226  /* get data to be read */
227  /* set chip select low to start transmission */
229 
230  /* send write command */
231  uint16_t write = FRAM_READCOMMAND;
232  SPI_FramTransmitReceiveData(&spi_framInterface, &write, &read, 1u);
233 
234  /* send upper part of address */
235  write = (address & 0x3F0000u) >> 16u;
236  SPI_FramTransmitReceiveData(&spi_framInterface, &write, &read, 1u);
237 
238  /* send middle part of address */
239  write = (address & 0xFF00u) >> 8u;
240  SPI_FramTransmitReceiveData(&spi_framInterface, &write, &read, 1u);
241 
242  /* send lower part of address */
243  write = address & 0xFFu;
244  SPI_FramTransmitReceiveData(&spi_framInterface, &write, &read, 1u);
245 
246  /* read CRC */
247  uint64_t crcRead = 0u;
248  uint8_t *pRead = (uint8_t *)(&crcRead);
249  for (uint8_t i = 0u; i < FRAM_CRC_HEADER_SIZE; i++) {
250  SPI_FramTransmitReceiveData(&spi_framInterface, &write, &read, 1u);
251  *pRead = (uint8_t)read;
252  pRead++;
253  }
254 
255  pRead = (uint8_t *)(fram_base_header[blockId].blockptr);
256 
257  /* read data */
258  write = 0;
259  while (size > 0u) {
260  SPI_FramTransmitReceiveData(&spi_framInterface, &write, &read, 1u);
261  *pRead = read & (uint8_t)UINT8_MAX;
262  pRead++;
263  size--;
264  }
265 
266  /* set chip select high to start transmission */
268 
270 
271  pRead = (uint8_t *)(fram_base_header[blockId].blockptr);
272  size = (fram_base_header[blockId]).datalength;
273  uint64_t crcCalculated = 0u;
274  STD_RETURN_TYPE_e crcRetVal = CRC_CalculateCrc(&crcCalculated, pRead, size);
275 
276  if (crcRetVal == STD_OK) {
277  if (crcRead != crcCalculated) {
279  retVal = FRAM_ACCESS_CRC_ERROR;
280  }
281  } else {
282  retVal = FRAM_ACCESS_CRC_BUSY;
283  }
284  } else {
285  retVal = FRAM_ACCESS_SPI_BUSY;
286  }
287 
288  return retVal;
289 }
290 
291 /*========== Externalized Static Function Implementations (Unit Test) =======*/
292 #ifdef UNITY_UNIT_TEST
293 #endif
STD_RETURN_TYPE_e CRC_CalculateCrc(uint64_t *pCrc, uint8_t *pData, uint32_t lengthInBytes)
Computes CRC of data flow.
Definition: crc.c:76
crc module header
DIAG_RETURNTYPE_e DIAG_Handler(DIAG_ID_e diagId, DIAG_EVENT_e event, DIAG_IMPACT_LEVEL_e impact, uint32_t data)
DIAG_Handler provides generic error handling, based on diagnosis group.
Definition: diag.c:246
Diagnosis driver header.
@ DIAG_EVENT_NOT_OK
Definition: diag_cfg.h:268
@ DIAG_EVENT_OK
Definition: diag_cfg.h:267
@ DIAG_SYSTEM
Definition: diag_cfg.h:280
@ DIAG_ID_FRAM_READ_CRC_ERROR
Definition: diag_cfg.h:259
Assert macro implementation.
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:255
void FRAM_Initialize(void)
Initializes the addresses to be written in the FRAM.
Definition: fram.c:96
#define FRAM_DELAY_AFTER_WRITE_ENABLE_US
Definition: fram.c:74
#define FRAM_READCOMMAND
Definition: fram.c:79
STD_RETURN_TYPE_e FRAM_ReinitializeAllEntries(void)
Reinitialize all entries in the FRAM.
Definition: fram.c:116
#define FRAM_WRITECOMMAND
Definition: fram.c:78
FRAM_RETURN_TYPE_e FRAM_ReadData(FRAM_BLOCK_ID_e blockId)
Reads a variable from the FRAM.
Definition: fram.c:211
FRAM_RETURN_TYPE_e FRAM_WriteData(FRAM_BLOCK_ID_e blockId)
Writes a variable to the FRAM.
Definition: fram.c:133
#define FRAM_MAX_ADDRESS
Definition: fram.c:84
#define FRAM_WRITEENABLECOMMAND
Definition: fram.c:80
Header for the driver for the FRAM module.
FRAM_BASE_HEADER_s fram_base_header[]
Definition: fram_cfg.c:86
FRAM_VERSION_s fram_version
Definition: fram_cfg.c:70
#define FRAM_PROJECT_ID_FOXBMS_BASELINE
Definition: fram_cfg.h:86
#define FRAM_CRC_HEADER_SIZE
Definition: fram_cfg.h:71
FRAM_RETURN_TYPE_e
Definition: fram_cfg.h:89
@ FRAM_ACCESS_SPI_BUSY
Definition: fram_cfg.h:91
@ FRAM_ACCESS_CRC_BUSY
Definition: fram_cfg.h:92
@ FRAM_ACCESS_CRC_ERROR
Definition: fram_cfg.h:93
@ FRAM_ACCESS_OK
Definition: fram_cfg.h:90
FRAM_BLOCK_ID_e
Definition: fram_cfg.h:104
@ FRAM_BLOCK_ID_VERSION
Definition: fram_cfg.h:105
@ FRAM_BLOCK_MAX
Definition: fram_cfg.h:112
Definition of foxBMS standard types.
STD_RETURN_TYPE_e
Definition: fstd_types.h:82
@ STD_OK
Definition: fstd_types.h:83
void IO_PinSet(volatile uint32_t *pRegisterAddress, uint32_t pin)
Set pin by writing in pin output register.
Definition: io.c:91
void IO_PinReset(volatile uint32_t *pRegisterAddress, uint32_t pin)
Reset pin by writing in pin output register.
Definition: io.c:98
Header for the driver for the IO module.
void MCU_Delay_us(uint32_t delay_us)
Wait blocking a certain time in microseconds.
Definition: mcu.c:89
Headers for the driver for the MCU module.
void SPI_FramTransmitReceiveData(SPI_INTERFACE_CONFIG_s *pSpiInterface, uint16 *pTxBuff, uint16 *pRxBuff, uint32 frameLength)
Transmits and receives data on SPI without DMA, wrapper for FRAM.
Definition: spi.c:279
STD_RETURN_TYPE_e SPI_Lock(uint8_t spi)
Locks SPI interfaces.
Definition: spi.c:402
void SPI_Unlock(uint8_t spi)
Unlocks SPI interfaces.
Definition: spi.c:419
uint8_t SPI_GetSpiIndex(spiBASE_t *pNode)
Returns index of SPI node.
Definition: spi.c:556
Headers for the driver for the SPI module.
SPI_INTERFACE_CONFIG_s spi_framInterface
Definition: spi_cfg.c:237
@ SPI_CHIP_SELECT_SOFTWARE
Definition: spi_cfg.h:118
FRAM_PROJECT_ID project
Definition: fram_cfg.h:122
uint8_t minor
Definition: fram_cfg.h:125
uint8_t major
Definition: fram_cfg.h:124
uint8_t patch
Definition: fram_cfg.h:126
SPI_CHIP_SELECT_TYPE_e csType
Definition: spi_cfg.h:130
volatile uint32_t * pGioPort
Definition: spi_cfg.h:128
spiBASE_t * pNode
Definition: spi_cfg.h:127
const uint8_t major
Definition: version_cfg.h:83
const uint8_t minor
Definition: version_cfg.h:84
const uint8_t patch
Definition: version_cfg.h:85
Header file for the version information that is generated by the toolchain.
const VER_VERSION_s ver_foxbmsVersionInformation