foxBMS  1.4.0
The foxBMS Battery Management System API Documentation
i2c.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 i2c.c
44  * @author foxBMS Team
45  * @date 2021-07-22 (date of creation)
46  * @updated 2022-07-28 (date of last update)
47  * @version v1.4.0
48  * @ingroup DRIVERS
49  * @prefix I2C
50  *
51  * @brief Driver for the I2C module
52  *
53  */
54 
55 /*========== Includes =======================================================*/
56 #include "i2c.h"
57 
58 #include "database.h"
59 #include "diag.h"
60 #include "dma.h"
61 #include "fsystem.h"
62 #include "mcu.h"
63 
64 /*========== Macros and Definitions =========================================*/
65 
66 /*========== Static Constant and Variable Definitions =======================*/
67 
68 /*========== Extern Constant and Variable Definitions =======================*/
69 
70 /*========== Static Function Prototypes =====================================*/
71 
72 /*========== Static Function Implementations ================================*/
73 
74 /*========== Extern Function Implementations ================================*/
75 extern void I2C_Initialize(void) {
76  i2cInit();
77 }
78 
79 extern STD_RETURN_TYPE_e I2C_Read(uint32_t slaveAddress, uint8_t readAddress, uint32_t nrBytes, uint8_t *readData) {
80  FAS_ASSERT(readData != NULL_PTR);
81 
82  STD_RETURN_TYPE_e retVal = STD_OK;
83  uint16_t timeout = I2C_TIMEOUT_ITERATIONS;
84  bool nack = false;
85  uint8_t *data = readData;
86  uint32_t count = nrBytes;
87 
88  if ((i2cREG1->STR & (uint32_t)I2C_BUSBUSY) == 0u) {
89  /* Clear bits */
90  i2cREG1->MDR &= ~((uint32_t)I2C_STOP_COND);
91  i2cREG1->MDR &= ~((uint32_t)I2C_START_COND);
92  i2cREG1->MDR &= ~((uint32_t)I2C_REPEATMODE);
93  i2cREG1->STR |= (uint32_t)I2C_TX_INT;
94  i2cREG1->STR |= (uint32_t)I2C_RX_INT;
95 
96  i2cSetMode(i2cREG1, (uint32_t)I2C_MASTER); /* Set as master */
97  i2cSetDirection(i2cREG1, (uint32_t)I2C_TRANSMITTER); /* Set as transmitter */
98  i2cSetSlaveAdd(i2cREG1, slaveAddress); /* Set slave address */
99  i2cSetCount(i2cREG1, 1u); /* Send 1 byte */
100  i2cSetStart(i2cREG1); /* Start write */
101  i2cREG1->DXR = (uint32_t)readAddress; /* Send register address */
102 
103  /* Wait until Tx buffer was copied to shift buffer */
104  timeout = I2C_TIMEOUT_ITERATIONS;
105  while (((i2cREG1->STR & (uint32_t)I2C_TX_INT) == 0u) && (timeout > 0u)) {
106  if ((i2cREG1->STR & (uint32_t)I2C_NACK) != 0u) {
107  nack = true;
108  break;
109  }
110  timeout--;
111  }
112 
113  if (timeout == 0u) {
114  /* Set repeat flag */
115  i2cREG1->MDR |= (uint32_t)I2C_REPEATMODE;
116  /* Set Stop condition */
117  i2cSetStop(i2cREG1);
118  timeout = I2C_TIMEOUT_ITERATIONS;
119  while ((i2cIsStopDetected(i2cREG1) == 0u) && (timeout > 0u)) {
120  timeout--;
121  }
122  retVal = STD_NOT_OK;
123  } else {
124  /* If slave ACK received, receive data */
125  if ((i2cREG1->STR & (uint32_t)I2C_NACK) == 0u) {
126  i2cSetMode(i2cREG1, (uint32_t)I2C_MASTER); /* Set as master */
127  i2cSetDirection(i2cREG1, (uint32_t)I2C_RECEIVER); /* Set as transmitter */
128  i2cSetCount(i2cREG1, nrBytes); /* Send count bytes before STOP condition */
129  i2cSetStart(i2cREG1); /* Start write */
130  i2cSetStop(i2cREG1); /* Stop condition after sending nrBytes bytes */
131 
132  /* Receive nrBytes bytes in polling mode */
133  while (count > 0u) {
134  timeout = I2C_TIMEOUT_ITERATIONS;
135  while (((i2cREG1->STR & (uint32_t)I2C_RX_INT) == 0u) && (timeout > 0u)) {
136  if ((i2cREG1->STR & (uint32_t)I2C_NACK_INT) != 0u) {
137  nack = true;
138  break;
139  }
140  timeout--;
141  }
142  if ((nack == true) || (timeout == 0u)) {
143  break;
144  }
145  *data = ((uint8)i2cREG1->DRR);
146  data++;
147  count--;
148  }
149  if ((nack == true) || (timeout == 0u)) {
150  /* Set repeat flag */
151  i2cREG1->MDR |= (uint32_t)I2C_REPEATMODE;
152  /* Set Stop condition */
153  i2cSetStop(i2cREG1);
154  timeout = I2C_TIMEOUT_ITERATIONS;
155  while ((i2cIsStopDetected(i2cREG1) == 0u) && (timeout > 0u)) {
156  timeout--;
157  }
158  retVal = STD_NOT_OK;
159  } else {
160  /* Wait until Stop is detected */
161  timeout = I2C_TIMEOUT_ITERATIONS;
162  while ((i2cIsStopDetected(i2cREG1) == 0u) && (timeout > 0u)) {
163  timeout--;
164  }
165  if (timeout == 0u) {
166  retVal = STD_NOT_OK;
167  } else {
168  i2cClearSCD(i2cREG1); /* Clear the Stop condition */
169  }
170  }
171  } else {
172  I2C_SetStopNow();
173  retVal = STD_NOT_OK;
174  }
175  }
176  } else {
177  I2C_SetStopNow();
178  retVal = STD_NOT_OK;
179  }
180 
181  return retVal;
182 }
183 
184 extern STD_RETURN_TYPE_e I2C_ReadDirect(uint32_t slaveAddress, uint32_t nrBytes, uint8_t *readData) {
185  FAS_ASSERT(readData != NULL_PTR);
186 
187  STD_RETURN_TYPE_e retVal = STD_OK;
188  uint16_t timeout = I2C_TIMEOUT_ITERATIONS;
189  bool nack = false;
190  uint8_t *data = readData;
191  uint32_t count = nrBytes;
192 
193  if ((i2cREG1->STR & (uint32_t)I2C_BUSBUSY) == 0u) {
194  /* Clear bits */
195  i2cREG1->MDR &= ~((uint32_t)I2C_STOP_COND);
196  i2cREG1->MDR &= ~((uint32_t)I2C_START_COND);
197  i2cREG1->MDR &= ~((uint32_t)I2C_REPEATMODE);
198  i2cREG1->STR |= (uint32_t)I2C_TX_INT;
199  i2cREG1->STR |= (uint32_t)I2C_RX_INT;
200  i2cREG1->STR |= (uint32_t)I2C_TX_INT;
201  i2cREG1->STR |= (uint32_t)I2C_RX_INT;
202 
203  i2cSetMode(i2cREG1, (uint32_t)I2C_MASTER); /* Set as master */
204  i2cSetDirection(i2cREG1, (uint32_t)I2C_RECEIVER); /* Set as transmitter */
205  i2cSetSlaveAdd(i2cREG1, slaveAddress); /* Set slave address */
206  i2cSetCount(i2cREG1, nrBytes); /* Send count bytes before STOP condition */
207  i2cSetStart(i2cREG1); /* Start write */
208  i2cSetStop(i2cREG1); /* Stop condition after sending nrBytes bytes */
209 
210  /* Receive nrBytes bytes in polling mode */
211  while (count > 0u) {
212  timeout = I2C_TIMEOUT_ITERATIONS;
213  while (((i2cREG1->STR & (uint32_t)I2C_RX_INT) == 0u) && (timeout > 0u)) {
214  if ((i2cREG1->STR & (uint32_t)I2C_NACK_INT) != 0u) {
215  nack = true;
216  break;
217  }
218  timeout--;
219  }
220  if ((nack == true) || (timeout == 0u)) {
221  break;
222  }
223  *data = ((uint8)i2cREG1->DRR);
224  data++;
225  count--;
226  }
227  if ((nack == true) || (timeout == 0u)) {
228  /* Set repeat flag */
229  i2cREG1->MDR |= (uint32_t)I2C_REPEATMODE;
230  /* Set Stop condition */
231  i2cSetStop(i2cREG1);
232  timeout = I2C_TIMEOUT_ITERATIONS;
233  while ((i2cIsStopDetected(i2cREG1) == 0u) && (timeout > 0u)) {
234  timeout--;
235  }
236  retVal = STD_NOT_OK;
237  } else {
238  /* Wait until Stop is detected */
239  timeout = I2C_TIMEOUT_ITERATIONS;
240  while ((i2cIsStopDetected(i2cREG1) == 0u) && (timeout > 0u)) {
241  timeout--;
242  }
243  if (timeout == 0u) {
244  retVal = STD_NOT_OK;
245  } else {
246  i2cClearSCD(i2cREG1); /* Clear the Stop condition */
247  }
248  }
249  } else {
250  I2C_SetStopNow();
251  retVal = STD_NOT_OK;
252  }
253 
254  return retVal;
255 }
256 
257 extern STD_RETURN_TYPE_e I2C_Write(uint32_t slaveAddress, uint8_t writeAddress, uint32_t nrBytes, uint8_t *writeData) {
258  FAS_ASSERT(writeData != NULL_PTR);
259 
260  STD_RETURN_TYPE_e retVal = STD_OK;
261  uint16_t timeout = I2C_TIMEOUT_ITERATIONS;
262  bool nack = false;
263  uint8_t *data = writeData;
264  uint32_t count = nrBytes;
265 
266  if ((i2cREG1->STR & (uint32_t)I2C_BUSBUSY) == 0u) {
267  /* Clear bits */
268  i2cREG1->MDR &= ~((uint32_t)I2C_STOP_COND);
269  i2cREG1->MDR &= ~((uint32_t)I2C_START_COND);
270  i2cREG1->MDR &= ~((uint32_t)I2C_REPEATMODE);
271  i2cREG1->STR |= (uint32_t)I2C_TX_INT;
272  i2cREG1->STR |= (uint32_t)I2C_RX_INT;
273 
274  i2cSetMode(i2cREG1, (uint32_t)I2C_MASTER); /* Set as master */
275  i2cSetDirection(i2cREG1, (uint32_t)I2C_TRANSMITTER); /* Set as transmitter */
276  i2cSetSlaveAdd(i2cREG1, slaveAddress); /* Set slave address */
277  i2cSetStop(i2cREG1); /* Stop condition after sending nrBytes bytes */
278  i2cSetCount(i2cREG1, nrBytes + 1u); /* Send count bytes before STOP condition */
279  i2cSetStart(i2cREG1); /* Start write */
280 
281  /* Send register address */
282  i2cREG1->DXR = (uint32_t)writeAddress;
283  /* Wait until Tx buffer was copied to shift buffer */
284  timeout = I2C_TIMEOUT_ITERATIONS;
285  while (((i2cREG1->STR & (uint32_t)I2C_TX_INT) == 0u) && (timeout > 0u)) {
286  if ((i2cREG1->STR & (uint32_t)I2C_NACK) != 0u) {
287  nack = true;
288  break;
289  }
290  timeout--;
291  }
292 
293  if (timeout == 0u) {
294  i2cREG1->MDR |= (uint32_t)I2C_REPEATMODE; /* Set repeat flag */
295  i2cSetStop(i2cREG1); /* Set Stop condition */
296 
297  timeout = I2C_TIMEOUT_ITERATIONS;
298  while ((i2cIsStopDetected(i2cREG1) == 0u) && (timeout > 0u)) {
299  timeout--;
300  }
301  retVal = STD_NOT_OK;
302  } else {
303  /* If slave ACK received, send data */
304  if ((i2cREG1->STR & (uint32_t)I2C_NACK) == 0u) {
305  /* Send nrBytes bytes in polling mode */
306  while (count > 0u) {
307  /* Wait until Tx buffer was copied to shift buffer */
308  timeout = I2C_TIMEOUT_ITERATIONS;
309  while (((i2cREG1->STR & (uint32_t)I2C_TX_INT) == 0u) && (timeout > 0u)) {
310  if ((i2cREG1->STR & (uint32_t)I2C_NACK) != 0u) {
311  nack = true;
312  break;
313  }
314  timeout--;
315  }
316  if ((nack == true) || (timeout == 0u)) {
317  break;
318  }
319  i2cREG1->DXR = (uint32_t)*data;
320  data++;
321  count--;
322  }
323  if ((nack == true) || (timeout == 0u)) {
324  i2cREG1->MDR |= (uint32_t)I2C_REPEATMODE; /* Set repeat flag */
325  i2cSetStop(i2cREG1); /* Set Stop condition */
326 
327  timeout = I2C_TIMEOUT_ITERATIONS;
328  while ((i2cIsStopDetected(i2cREG1) == 0u) && (timeout > 0u)) {
329  timeout--;
330  }
331  retVal = STD_NOT_OK;
332  } else {
333  /* Wait until Stop is detected */
334  timeout = I2C_TIMEOUT_ITERATIONS;
335  while ((i2cIsStopDetected(i2cREG1) == 0u) && (timeout > 0u)) {
336  timeout--;
337  }
338  if (timeout == 0u) {
339  retVal = STD_NOT_OK;
340  } else {
341  i2cClearSCD(i2cREG1); /* Clear the Stop condition */
342  }
343  }
344  } else {
345  I2C_SetStopNow();
346  retVal = STD_NOT_OK;
347  }
348  }
349  } else {
350  I2C_SetStopNow();
351  retVal = STD_NOT_OK;
352  }
353 
354  return retVal;
355 }
356 
357 extern STD_RETURN_TYPE_e I2C_WriteDirect(uint32_t slaveAddress, uint32_t nrBytes, uint8_t *writeData) {
358  FAS_ASSERT(writeData != NULL_PTR);
359 
360  STD_RETURN_TYPE_e retVal = STD_OK;
361  uint16_t timeout = I2C_TIMEOUT_ITERATIONS;
362  bool nack = false;
363  uint8_t *data = writeData;
364  uint32_t count = nrBytes;
365 
366  if ((i2cREG1->STR & (uint32_t)I2C_BUSBUSY) == 0u) {
367  /* Clear bits */
368  i2cREG1->MDR &= ~((uint32_t)I2C_STOP_COND);
369  i2cREG1->MDR &= ~((uint32_t)I2C_START_COND);
370  i2cREG1->MDR &= ~((uint32_t)I2C_REPEATMODE);
371  i2cREG1->STR |= (uint32_t)I2C_TX_INT;
372  i2cREG1->STR |= (uint32_t)I2C_RX_INT;
373 
374  i2cSetMode(i2cREG1, (uint32_t)I2C_MASTER); /* Set as master */
375  i2cSetDirection(i2cREG1, (uint32_t)I2C_TRANSMITTER); /* Set as transmitter */
376  i2cSetSlaveAdd(i2cREG1, slaveAddress); /* Set slave address */
377  i2cSetStop(i2cREG1); /* Stop condition after sending nrBytes bytes */
378  i2cSetCount(i2cREG1, nrBytes); /* Send count bytes before STOP condition */
379  i2cSetStart(i2cREG1); /* Start write */
380 
381  /* If slave ACK received, send data */
382  if ((i2cREG1->STR & (uint32_t)I2C_NACK) == 0u) {
383  /* Send nrBytes bytes in polling mode */
384  while (count > 0u) {
385  /* Wait until Tx buffer was copied to shift buffer */
386  timeout = I2C_TIMEOUT_ITERATIONS;
387  while (((i2cREG1->STR & (uint32_t)I2C_TX_INT) == 0u) && (timeout > 0u)) {
388  if ((i2cREG1->STR & (uint32_t)I2C_NACK) != 0u) {
389  nack = true;
390  break;
391  }
392  timeout--;
393  }
394  if ((nack == true) || (timeout == 0u)) {
395  break;
396  }
397  i2cREG1->DXR = (uint32_t)*data;
398  data++;
399  count--;
400  }
401  if ((nack == true) || (timeout == 0u)) {
402  i2cREG1->MDR |= (uint32_t)I2C_REPEATMODE; /* Set repeat flag */
403  i2cSetStop(i2cREG1); /* Set Stop condition */
404 
405  timeout = I2C_TIMEOUT_ITERATIONS;
406  while ((i2cIsStopDetected(i2cREG1) == 0u) && (timeout > 0u)) {
407  timeout--;
408  }
409  retVal = STD_NOT_OK;
410  } else {
411  /* Wait until Stop is detected */
412  timeout = I2C_TIMEOUT_ITERATIONS;
413  while ((i2cIsStopDetected(i2cREG1) == 0u) && (timeout > 0u)) {
414  timeout--;
415  }
416  if (timeout == 0u) {
417  retVal = STD_NOT_OK;
418  } else {
419  i2cClearSCD(i2cREG1); /* Clear the Stop condition */
420  }
421  }
422  } else {
423  I2C_SetStopNow();
424  retVal = STD_NOT_OK;
425  }
426  } else {
427  I2C_SetStopNow();
428  retVal = STD_NOT_OK;
429  }
430 
431  return retVal;
432 }
433 
434 extern STD_RETURN_TYPE_e I2C_ReadDma(uint32_t slaveAddress, uint8_t readAddress, uint32_t nrBytes, uint8_t *readData) {
435  FAS_ASSERT(readData != NULL_PTR);
436 
437  STD_RETURN_TYPE_e retVal = STD_OK;
438  uint16_t timeout = I2C_TIMEOUT_ITERATIONS;
439 
440  if ((i2cREG1->STR & (uint32_t)I2C_BUSBUSY) == 0u) {
442 
443  /* Go to privileged mode to write DMA config registers */
444  const int32_t raisePrivilegeResult = FSYS_RaisePrivilege();
445  FAS_ASSERT(raisePrivilegeResult == 0);
446 
447  /* Set Tx buffer address */
448  /* AXIVION Next Codeline Style MisraC2012-1.1: Cast necessary for DMA configuration */
449  dmaRAMREG->PCP[(dmaChannel_t)DMA_CHANNEL_I2C_RX].IDADDR = (uint32_t)readData;
450  /* Set number of Tx bytes to transmit */
451  dmaRAMREG->PCP[(dmaChannel_t)DMA_CHANNEL_I2C_RX].ITCOUNT = (nrBytes << 16U) | 1U;
452 
453  dmaSetChEnable((dmaChannel_t)DMA_CHANNEL_I2C_RX, (dmaTriggerType_t)DMA_HW);
454 
455  FSYS_SWITCH_TO_USER_MODE(); /* DMA config registers written, leave privileged mode */
457 
458  i2cREG1->DMACR |= (uint32_t)I2C_RXDMAEN; /* Activate I2C DMA RX */
459 
460  i2cSetMode(i2cREG1, (uint32_t)I2C_MASTER); /* Set to master */
461  i2cSetDirection(i2cREG1, (uint32_t)I2C_TRANSMITTER); /* Set as transmitter */
462  i2cSetSlaveAdd(i2cREG1, slaveAddress); /* Set slave address */
463  i2cSetCount(i2cREG1, 1u); /* Write one byte to select register address */
464  i2cSetStart(i2cREG1); /* Start write */
465  i2cSendByte(i2cREG1, readAddress); /* Transmit register address */
466 
467  /* Wait until Tx buffer was copied to shift buffer */
468  while ((i2cREG1->STR & (uint32_t)I2C_TX_INT) == 0u) {
469  if ((i2cREG1->STR & (uint32_t)I2C_NACK) != 0u) {
470  break;
471  }
472  }
473 
474  if ((i2cREG1->STR & (uint32_t)I2C_NACK) == 0u) {
475  i2cSetDirection(i2cREG1, (uint32_t)I2C_RECEIVER); /* Set as receiver */
476  i2cSetCount(i2cREG1, nrBytes); /* Receive nrBytes before STOP condition */
477  i2cSetMode(i2cREG1, (uint32_t)I2C_MASTER); /* Set as master */
478  i2cSetStop(i2cREG1); /* Stop condition after receiving nrBytes bytes */
479  i2cSetStart(i2cREG1); /* Set start while bus busy for REPEATED START condition */
480  } else {
481  i2cREG1->STR |= (uint32_t)I2C_NACK; /* Clear NACK flag */
482  i2cREG1->STR |= (uint32_t)I2C_TX_INT; /* Set Tx ready flag */
483  i2cSetStop(i2cREG1); /* Set Stop condition */
484 
485  /* Wait until Stop is detected */
486  timeout = I2C_TIMEOUT_ITERATIONS;
487  while ((i2cIsStopDetected(i2cREG1) == 0u) && (timeout > 0u)) {
488  timeout--;
489  }
490 
491  i2cClearSCD(i2cREG1); /* Clear the Stop condition */
492  retVal = STD_NOT_OK;
493  }
494  } else {
495  retVal = STD_NOT_OK;
496  }
497 
498  return retVal;
499 }
500 
502  uint32_t slaveAddress,
503  uint8_t writeAddress,
504  uint32_t nrBytes,
505  uint8_t *writeData) {
506  FAS_ASSERT(writeData != NULL_PTR);
507 
508  STD_RETURN_TYPE_e retVal = STD_OK;
509  uint16_t timeout = I2C_TIMEOUT_ITERATIONS;
510 
511  if ((i2cREG1->STR & (uint32_t)I2C_BUSBUSY) == 0u) {
513 
514  /* Go to privileged mode to write DMA config registers */
515  const int32_t raisePrivilegeResult = FSYS_RaisePrivilege();
516  FAS_ASSERT(raisePrivilegeResult == 0);
517 
518  /* Set Tx buffer address */
519  /* AXIVION Next Codeline Style MisraC2012-1.1: Cast necessary for DMA configuration */
520  dmaRAMREG->PCP[(dmaChannel_t)DMA_CHANNEL_I2C_TX].ISADDR = (uint32_t)writeData;
521 
522  /* Set number of Tx bytes to transmit */
523  dmaRAMREG->PCP[(dmaChannel_t)DMA_CHANNEL_I2C_TX].ITCOUNT = (nrBytes << 16U) | 1U;
524 
525  dmaSetChEnable((dmaChannel_t)DMA_CHANNEL_I2C_TX, (dmaTriggerType_t)DMA_HW);
526 
527  FSYS_SWITCH_TO_USER_MODE(); /* DMA config registers written, leave privileged mode */
529 
530  i2cSetMode(i2cREG1, (uint32_t)I2C_MASTER); /* Set as master */
531  i2cSetDirection(i2cREG1, (uint32_t)I2C_TRANSMITTER); /* Set as transmitter */
532  i2cSetSlaveAdd(i2cREG1, slaveAddress); /* Set slave address */
533  i2cSetStop(i2cREG1); /* Stop condition after sending nrBytes bytes */
534  i2cSetCount(i2cREG1, nrBytes + 1u); /* Send (nrBytes+1) before STOP condition (includes register address)*/
535  i2cSendByte(i2cREG1, writeAddress); /* Send register address */
536  i2cREG1->DMACR |= (uint32_t)I2C_TXDMAEN; /* Activate I2C DMA TX */
537  i2cSetStart(i2cREG1); /* Start write */
538 
539  /* Wait until Tx buffer was copied to shift buffer */
540  while ((i2cREG1->STR & (uint32_t)I2C_TX_INT) == 0u) {
541  if ((i2cREG1->STR & (uint32_t)I2C_NACK) != 0u) {
542  break;
543  }
544  }
545 
546  if ((i2cREG1->STR & (uint32_t)I2C_NACK) != 0u) {
547  i2cREG1->STR |= (uint32_t)I2C_NACK; /* Clear NACK flag */
548  i2cREG1->STR |= (uint32_t)I2C_TX_INT; /* Set Tx ready flag */
549  i2cSetStop(i2cREG1); /* Set Stop condition */
550  timeout = I2C_TIMEOUT_ITERATIONS; /* Wait until Stop is detected */
551 
552  while ((i2cIsStopDetected(i2cREG1) == 0u) && (timeout > 0u)) {
553  timeout--;
554  }
555 
556  i2cClearSCD(i2cREG1); /* Clear the Stop condition */
557  i2cREG1->STR &= ~(uint32_t)I2C_REPEATMODE;
558  retVal = STD_NOT_OK;
559  }
560  } else {
561  retVal = STD_NOT_OK;
562  }
563 
564  return retVal;
565 }
566 
567 extern void I2C_SetStopNow(void) {
568  /* Clear bits */
569  i2cREG1->MDR &= ~((uint32_t)I2C_STOP_COND);
570  i2cREG1->MDR &= ~((uint32_t)I2C_START_COND);
571  i2cREG1->MDR &= ~((uint32_t)I2C_REPEATMODE);
572  i2cREG1->STR |= (uint32_t)I2C_TX_INT;
573  i2cREG1->STR |= (uint32_t)I2C_RX_INT;
574 
575  i2cREG1->MDR |= (uint32_t)I2C_REPEATMODE; /* Set repeat flag */
576  i2cSetMode(i2cREG1, (uint32_t)I2C_MASTER); /* Set as master */
577  i2cSetDirection(i2cREG1, (uint32_t)I2C_TRANSMITTER); /* Set as transmitter */
578  i2cSetStop(i2cREG1); /* Set Stop condition */
579 
580  while (i2cIsStopDetected(i2cREG1) == 0u) {
581  }
582 
583  i2cREG1->MDR &= ~(uint32_t)I2C_REPEATMODE; /* Reset repeat flag */
584  i2cClearSCD(i2cREG1); /* Clear the Stop condition */
585 }
586 
587 /*========== Getter for static Variables (Unit Test) ========================*/
588 #ifdef UNITY_UNIT_TEST
589 
590 #endif
591 
592 /*========== Externalized Static Function Implementations (Unit Test) =======*/
Database module header.
Diagnosis driver header.
Headers for the driver for the DMA module.
#define DMA_CHANNEL_I2C_TX
Definition: dma_cfg.h:81
#define DMA_CHANNEL_I2C_RX
Definition: dma_cfg.h:82
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:252
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
Function to switch between user mode and privilege mode.
#define FSYS_SWITCH_TO_USER_MODE()
Switch back to user mode.
Definition: fsystem.h:129
long FSYS_RaisePrivilege(void)
Raise privilege.
STD_RETURN_TYPE_e I2C_WriteDirect(uint32_t slaveAddress, uint32_t nrBytes, uint8_t *writeData)
writes to an I2C slave, no register address written first, blocking.
Definition: i2c.c:357
void I2C_SetStopNow(void)
sets stop condition.
Definition: i2c.c:567
STD_RETURN_TYPE_e I2C_ReadDma(uint32_t slaveAddress, uint8_t readAddress, uint32_t nrBytes, uint8_t *readData)
reads from an I2C slave, using DMA.
Definition: i2c.c:434
STD_RETURN_TYPE_e I2C_Write(uint32_t slaveAddress, uint8_t writeAddress, uint32_t nrBytes, uint8_t *writeData)
writes to an I2C slave, blocking.
Definition: i2c.c:257
STD_RETURN_TYPE_e I2C_ReadDirect(uint32_t slaveAddress, uint32_t nrBytes, uint8_t *readData)
reads from an I2C slave, no register address written first, blocking.
Definition: i2c.c:184
void I2C_Initialize(void)
Definition: i2c.c:75
STD_RETURN_TYPE_e I2C_WriteDma(uint32_t slaveAddress, uint8_t writeAddress, uint32_t nrBytes, uint8_t *writeData)
writes to an I2C slave, using DMA.
Definition: i2c.c:501
STD_RETURN_TYPE_e I2C_Read(uint32_t slaveAddress, uint8_t readAddress, uint32_t nrBytes, uint8_t *readData)
reads from an I2C slave, blocking.
Definition: i2c.c:79
Header for the driver for the I2C module.
#define I2C_RXDMAEN
Definition: i2c.h:71
#define I2C_TIMEOUT_ITERATIONS
Definition: i2c.h:66
#define I2C_TXDMAEN
Definition: i2c.h:69
Headers for the driver for the MCU module.
void OS_ExitTaskCritical(void)
Exit Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os_freertos.c:135
void OS_EnterTaskCritical(void)
Enter Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os_freertos.c:131