iLLD_TC23x  1.0
IfxMtu.c
Go to the documentation of this file.
1 /**
2  * \file IfxMtu.c
3  * \brief MTU basic functionality
4  *
5  * \version iLLD_1_0_0_11_0
6  * \copyright Copyright (c) 2013 Infineon Technologies AG. All rights reserved.
7  *
8  *
9  * IMPORTANT NOTICE
10  *
11  *
12  * Infineon Technologies AG (Infineon) is supplying this file for use
13  * exclusively with Infineon's microcontroller products. This file can be freely
14  * distributed within development tools that are supporting such microcontroller
15  * products.
16  *
17  * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
18  * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
20  * INFINEON SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
21  * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
22  *
23  *
24  */
25 
26 /******************************************************************************/
27 /*----------------------------------Includes----------------------------------*/
28 /******************************************************************************/
29 
30 #include "IfxMtu.h"
31 
32 /** \addtogroup IfxLld_Mtu_Std_Utility
33  * \{ */
34 
35 /******************************************************************************/
36 /*-----------------------Private Function Prototypes--------------------------*/
37 /******************************************************************************/
38 
39 /** \brief API to wait for requested tower depth.
40  * \param towerDepth tower depth of MBIST Ram
41  * \param numInstructions number of instructions
42  * \param mbistSel Memory Selection
43  * \return None
44  */
45 static void IfxMtu_waitForMbistDone(uint32 towerDepth, uint8 numInstructions, IfxMtu_MbistSel mbistSel);
46 
47 /** \} */
48 
49 /******************************************************************************/
50 /*-------------------------Function Implementations---------------------------*/
51 /******************************************************************************/
52 
54 {
55  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
56  mc->ECCD.U |= (1 << IFX_MC_ECCD_TRC_OFF);
57 }
58 
59 
61 {
62  uint8 isEndInitEnabled = 0;
63  uint16 password = 0;
64 
66 
67  /* Check if the Endinit is cleared by application. If not, then handle it internally inside teh function.*/
69  {
70  /* Clear EndInit */
72  isEndInitEnabled = 1;
73  }
74 
75  IfxMtu_clearSramStart(mbistSel);
76 
77  /* Set EndInit Watchdog (to prevent Watchdog TO)*/
79 
80  /* wait for the end of the fill operation */
81  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
82  IfxMtu_waitForMbistDone(IfxMtu_sramTable[mbistSel].mbistDelay, 1, mbistSel);
83  IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, mc->MSTATUS.B.DONE != 0);
84 
85  while (!IfxMtu_isMbistDone(mbistSel))
86  {
87  __nop();
88  }
89 
90  /* Clear EndInit */
92 
93  IfxMtu_clearSramContinue(mbistSel);
94 
95  if (isEndInitEnabled == 1)
96  {
97  /* Set EndInit Watchdog (to prevent Watchdog TO)*/
99  }
100 }
101 
102 
104 {
105  /* Before clearing the ECC error flags we've to issue a dummy SRAM access to get a valid memory output */
106  IfxMtu_readSramAddress(mbistSel, 0x0000);
107 
108  /* Note: a SMU alarm will be flagged HERE if the wrong ECC has been written! */
109  IfxMtu_disableMbistShell(mbistSel);
110 
111  /* for auto-init memories: wait for the end of the clear operation */
112  while (IfxMtu_isAutoInitRunning(mbistSel))
113  {}
114 }
115 
116 
118 {
119  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
120 
121  IfxMtu_enableMbistShell(mbistSel);
122 
123  /* for auto-init memories: wait for the end of the clear operation */
124  while (IfxMtu_isAutoInitRunning(mbistSel))
125  {}
126 
127  /* write valid ECC code for all-zero data into RDBFL registers */
128  {
130  const IfxMtu_SramItem *item = (IfxMtu_SramItem *)&IfxMtu_sramTable[mbistSel];
131 
132  uint8 numBlocks = item->numBlocks;
133  IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, numBlocks > 0);
134 
135  uint16 dataSize = item->dataSize;
136  uint8 eccSize = item->eccSize;
137  uint32 eccInvPos0 = dataSize + item->eccInvPos0;
138  uint32 eccInvPos1 = dataSize + item->eccInvPos1;
139 
140  uint32 memSize = dataSize + eccSize;
141 
142  uint32 bitPos = 0;
143  uint32 wordIx = 0;
144  uint16 data = 0;
145  /* de-serialize data stream into 16bit packets */
146  uint32 mem;
147 
148  for (mem = 0; mem < numBlocks; ++mem)
149  {
150  uint32 i;
151 
152  for (i = 0; i < memSize; ++i)
153  {
154  if ((i == eccInvPos0) || (i == eccInvPos1))
155  {
156  data |= (1 << bitPos);
157  }
158 
159  ++bitPos;
160 
161  if (bitPos >= 16)
162  {
163  mc->RDBFL[wordIx++].U = data;
164  bitPos = 0;
165  data = 0;
166  }
167  }
168  }
169 
170  /* final word? */
171  if (bitPos != 0)
172  {
173  mc->RDBFL[wordIx].U = data;
174  }
175  }
176 
177  /* start fill operation */
178  uint16 mcontrolMask = 0x4000; /* set USERED flag */
179  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DINIT_OFF) | (1 << IFX_MC_MCONTROL_START_OFF); /* START = DINIT = 1 */
180  mc->MCONTROL.U = mcontrolMask | (0 << IFX_MC_MCONTROL_DINIT_OFF) | (1 << IFX_MC_MCONTROL_DINIT_OFF); /* START = 0 */
181 }
182 
183 
185 {
186  volatile uint32 *mtuMemtest = (volatile uint32 *)((uint32)&MTU_MEMTEST0 + 4 * (mbistSel >> 5));
187  uint32 mask = 1 << (mbistSel & 0x1f);
188  *mtuMemtest &= ~mask;
189 }
190 
191 
193 {
194  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
195 
196  if (enable == FALSE)
197  {
198  mc->ECCS.U &= ~(1 << IFX_MC_ECCS_TRE_OFF);
199  }
200  else
201  {
202  mc->ECCS.U |= (1 << IFX_MC_ECCS_TRE_OFF);
203  }
204 }
205 
206 
208 {
209  volatile uint32 *mtuMemtest = (volatile uint32 *)((uint32)&MTU_MEMTEST0 + 4 * (mbistSel >> 5));
210  uint32 mask = 1 << (mbistSel & 0x1f);
211  *mtuMemtest |= mask;
212 }
213 
214 
215 uint32 IfxMtu_getSystemAddress(IfxMtu_MbistSel mbistSel, Ifx_MC_ETRR trackedSramAddress)
216 {
217  uint32 sramAddress = trackedSramAddress.B.ADDR;
218  uint32 mbi = trackedSramAddress.B.MBI;
219  uint32 systemAddress = 0;
220 
221  switch (mbistSel)
222  {
224  systemAddress = 0x70100000 | ((sramAddress << 3) | ((mbi & 1) << 2));
225  break;
226 
228  systemAddress = 0x70000000 | ((sramAddress << 4) | ((mbi & 3) << 2));
229  break;
230 
231  case IfxMtu_MbistSel_lmu:
232  systemAddress = 0xb0000000 | (sramAddress << 3);
233  break;
234 
235  default:
236  systemAddress = 0; /* unsupported address descrambling */
237  }
238 
239  return systemAddress;
240 }
241 
242 
243 uint8 IfxMtu_getTrackedSramAddresses(IfxMtu_MbistSel mbistSel, Ifx_MC_ETRR *trackedSramAddresses)
244 {
245  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
246  uint8 validFlags = (mc->ECCD.U >> IFX_MC_ECCD_VAL_OFF) & IFX_MC_ECCD_VAL_MSK;
247  uint8 numTrackedAddresses = 0;
248  int i;
249 
250 #if IFX_MC_ECCD_VAL_LEN > IFXMTU_MAX_TRACKED_ADDRESSES
251 # error "Unexpected size of VAL mask"
252 #endif
253 
254  for (i = 0; i < IFXMTU_MAX_TRACKED_ADDRESSES; ++i)
255  {
256  if (validFlags & (1 << i))
257  {
258  trackedSramAddresses[numTrackedAddresses].U = mc->ETRR[i].U;
259  ++numTrackedAddresses;
260  }
261  }
262 
263  return numTrackedAddresses;
264 }
265 
266 
268 {
269  volatile uint32 *mtuMemstat = (volatile uint32 *)((uint32)&MTU_MEMSTAT0 + 4 * (mbistSel >> 5));
270  uint32 mask = 1 << (mbistSel & 0x1f);
271  return (*mtuMemstat & mask) != 0;
272 }
273 
274 
276 {
277  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
278  return mc->ECCS.B.TRE ? TRUE : FALSE;
279 }
280 
281 
283 {
284  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
285  return mc->ECCD.B.EOV ? TRUE : FALSE;
286 }
287 
288 
290 {
291  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
292  uint16 status;
293 
294  status = mc->MSTATUS.U;
295  return (boolean)(status & 0x01);
296 }
297 
298 
299 void IfxMtu_readSramAddress(IfxMtu_MbistSel mbistSel, uint16 sramAddress)
300 {
301  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
302 
303  /* configure MBIST for single read opeation */
304  uint16 mcontrolMask = 0x4000; /* set USERED flag */
305  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DIR_OFF);
306  mc->CONFIG0.U = (1 << IFX_MC_CONFIG0_NUMACCS_OFF) | (1 << IFX_MC_CONFIG0_ACCSTYPE_OFF); /* 1 read access */
307  mc->CONFIG1.U = 0; /* ensure that linear scrambling is used */
308 
309  /* Set the address to be read (RAEN = 0) */
310  mc->RANGE.U = sramAddress;
311 
312  /* Start operation */
313  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DIR_OFF) | (1 << IFX_MC_MCONTROL_START_OFF);
314  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DIR_OFF);
315 
316  /* wait for the end of the fill operation */
317  IfxMtu_waitForMbistDone(256, 1, mbistSel);
318 
319  while (!IfxMtu_isMbistDone(mbistSel))
320  {
321  __nop();
322  }
323 }
324 
325 
326 uint8 IfxMtu_runCheckerBoardTest(IfxMtu_MbistSel mbistSel, uint8 rangeSel, uint8 rangeAddrUp, uint8 rangeAddrLow, uint16 *errorAddr, uint32 numberRedundancyLines)
327 {
328  /* Select MBIST Memory Controller:
329  * Ifx_MC is a type describing structure of MBIST Memory Controller
330  * registers defined in IfxMc_regdef.h file - MC object */
331  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
332  uint32 configCheckerBoardSequence[4] = {
333  0x08001000, //up /lin/w0
334  0x08001001, //up /lin/r0
335  0x00011000, //down/lin/w1
336  0x00011001
337  }; //down/lin/r1
338  uint16 password = 0;
339  uint8 retVal = 0U;
340  uint8 testStep;
341  uint8 isEndInitEnabled = 0;
343 
344  /* Check if the Endinit is cleared by application. If not, then handle it internally inside teh function.*/
346  {
347  /* Clear EndInit */
349  isEndInitEnabled = 1;
350  }
351 
352  /* Enable MBIST Memory Controller */
353  IfxMtu_enableMbistShell(mbistSel);
354 
355  /* for auto-init memories: wait for the end of the clear operation */
356  while (IfxMtu_isAutoInitRunning(mbistSel))
357  {}
358 
359  /* Set the range register */
360  mc->RANGE.U = (rangeSel << 15) | (rangeAddrUp << 7) | (rangeAddrLow << 0);
361 
362  /* Run the test */
363  for (testStep = 0; testStep < 4; ++testStep)
364  {
365  mc->CONFIG0.U = configCheckerBoardSequence[testStep] & 0x0000FFFF;
366  mc->CONFIG1.U = (configCheckerBoardSequence[testStep] & 0xFFFF0000) >> 16;
367  mc->MCONTROL.U = numberRedundancyLines ? 0x30c9 : 0x00c9; // bit and row toggle
368  mc->MCONTROL.U = numberRedundancyLines ? 0x30c8 : 0x00c8; // MCONTROL.B.START will generate a RMW which is too long for small SRAMs!
369 
370  /* Set EndInit Watchdog (to prevent Watchdog TO)*/
371  IfxScuWdt_setSafetyEndinit(password);
372 
373  /* wait for the end of the fill operation */
374  IfxMtu_waitForMbistDone(IfxMtu_sramTable[mbistSel].mbistDelay, 4, mbistSel);
375  IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, mc->MSTATUS.B.DONE != 0);
376 
377  while (!IfxMtu_isMbistDone(mbistSel))
378  {
379  __nop();
380  }
381 
382  /* Clear EndInit Again */
384 
385  /* Check the Fail Status */
386  if (mc->MSTATUS.B.FAIL)
387  {
388  /* Test has failed, check if any un-correctable error */
389  if (mc->ECCD.B.UERR)
390  {
391  /* Read Error tracking register and return saying test failed */
392  *errorAddr = mc->ETRR[0].U;
393  retVal = 1U;
394  break;
395  }
396  }
397  }
398 
399  /* Disable Memory Controller */
400 
401  IfxMtu_disableMbistShell(mbistSel);
402 
403  while (IfxMtu_isAutoInitRunning(mbistSel))
404  {}
405 
406  if (isEndInitEnabled == 1)
407  {
408  /* Set EndInit Watchdog (to prevent Watchdog TO)*/
409  IfxScuWdt_setSafetyEndinit(password);
410  }
411 
412  return retVal;
413 }
414 
415 
416 uint8 IfxMtu_runMarchUTest(IfxMtu_MbistSel mbistSel, uint8 rangeSel, uint8 rangeAddrUp, uint8 rangeAddrLow, uint16 *errorAddr)
417 {
418  /* Select MBIST Memory Controller:
419  * Ifx_MC is a type describing structure of MBIST Memory Controller
420  * registers defined in IfxMc_regdef.h file - MC object */
421  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
422  uint32 configMarchUSequence[6] = {
423  0x08001000, //up /lin/w0
424  0x08064005, //up /lin/r0->w1->r1->w0
425  0x08022001, //up /lin/r0->w1
426  0x00094005, //down/lin/r1->w0->r0->w1
427  0x00012001, //down/lin/r1->w0
428  0x00001001
429  }; //down/lin/r0
430  uint16 password = 0;
431  uint8 retVal = 0U;
432  uint8 testStep;
433  uint8 isEndInitEnabled = 0;
435 
436  /* Check if the Endinit is cleared by application. If not, then handle it internally inside teh function.*/
438  {
439  /* Clear EndInit */
441  isEndInitEnabled = 1;
442  }
443 
444  /* Enable MBIST Memory Controller */
445  IfxMtu_enableMbistShell(mbistSel);
446 
447  /* for auto-init memories: wait for the end of the clear operation */
448  while (IfxMtu_isAutoInitRunning(mbistSel))
449  {}
450 
451  /* Set the range register */
452  mc->RANGE.U = (rangeSel << 15) | (rangeAddrUp << 7) | (rangeAddrLow << 0);
453 
454  /* Run the test */
455  for (testStep = 0; testStep < 6; ++testStep)
456  {
457  mc->CONFIG0.U = configMarchUSequence[testStep] & 0x0000FFFF;
458  mc->CONFIG1.U = (configMarchUSequence[testStep] & 0xFFFF0000) >> 16;
459  mc->MCONTROL.U = 0x0209;
460  mc->MCONTROL.B.START = 0;
461 
462  /* Set EndInit Watchdog (to prevent Watchdog TO)*/
463  IfxScuWdt_setSafetyEndinit(password);
464 
465  /* wait for the end of the fill operation */
466  IfxMtu_waitForMbistDone(IfxMtu_sramTable[mbistSel].mbistDelay, 4, mbistSel);
467  IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, mc->MSTATUS.B.DONE != 0);
468 
469  while (!IfxMtu_isMbistDone(mbistSel))
470  {
471  __nop();
472  }
473 
474  /* Clear EndInit Again */
476 
477  /* Check the Fail Status */
478  if (mc->MSTATUS.B.FAIL)
479  {
480  /* Test has failed, check if any un-correctable error */
481  if (mc->ECCD.B.UERR)
482  {
483  /* Read Error tracking register and return saying test failed */
484  *errorAddr = mc->ETRR[0].U;
485  retVal = 1U;
486  break;
487  }
488  }
489  }
490 
491  /* Disable Memory Controller */
492  IfxMtu_disableMbistShell(mbistSel);
493 
494  /* for auto-init memories: wait for the end of the clear operation */
495  while (IfxMtu_isAutoInitRunning(mbistSel))
496  {}
497 
498  /* Restore the endinit state */
499  if (isEndInitEnabled == 1)
500  {
501  /* Set EndInit Watchdog (to prevent Watchdog TO)*/
502  IfxScuWdt_setSafetyEndinit(password);
503  }
504 
505  return retVal;
506 }
507 
508 
509 uint8 IfxMtu_runNonDestructiveInversionTest(IfxMtu_MbistSel mbistSel, uint8 rangeSel, uint8 rangeAddrUp, uint8 rangeAddrLow, uint16 *errorAddr)
510 {
511  /* Select MBIST Memory Controller:
512  * Ifx_MC is a type describing structure of MBIST Memory Controller
513  * registers defined in IfxMc_regdef.h file - MC object */
514  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
515  uint16 password = 0;
516  uint8 retVal = 0U;
517  uint8 isEndInitEnabled = 0;
519 
520  /* Check if the Endinit is cleared by application. If not, then handle it internally inside teh function.*/
522  {
523  /* Clear EndInit */
525  isEndInitEnabled = 1;
526  }
527 
528  /* Enable MBIST Memory Controller */
529  IfxMtu_enableMbistShell(mbistSel);
530 
531  /* for auto-init memories: wait for the end of the clear operation */
532  while (IfxMtu_isAutoInitRunning(mbistSel))
533  {}
534 
535  /* Configure Non-destructive Inversion test */
536  mc->CONFIG0.U = 0x4005; //NUMACCS=4, ACCSTYPE=5
537  mc->CONFIG1.U = 0x5000; //AG_MOD=5
538  /* Set the range register */
539  mc->RANGE.U = (rangeSel << 15) | (rangeAddrUp << 7) | (rangeAddrLow << 0);
540  /* Run the tests */
541  mc->MCONTROL.U = 0xF201;
542  mc->MCONTROL.B.START = 0;
543  /* Set EndInit Watchdog (to prevent Watchdog TO)*/
544  IfxScuWdt_setSafetyEndinit(password);
545 
546  /* wait for the end of the fill operation */
547  IfxMtu_waitForMbistDone(IfxMtu_sramTable[mbistSel].mbistDelay, 4, mbistSel);
548  IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, mc->MSTATUS.B.DONE != 0);
549 
550  while (!IfxMtu_isMbistDone(mbistSel))
551  {
552  __nop();
553  }
554 
555  /* Clear EndInit Again */
557 
558  /* Check the Fail Status */
559  if (mc->MSTATUS.B.FAIL)
560  {
561  /* Test has failed, check if any un-correctable error */
562  if (mc->ECCD.B.UERR)
563  {
564  /* Read the Error tracking register and return saying test failed */
565  *errorAddr = mc->ETRR[0].U;
566  retVal = 1U;
567  }
568  }
569 
570  /* Disable Memory Controller */
571  IfxMtu_disableMbistShell(mbistSel);
572 
573  /* for auto-init memories: wait for the end of the clear operation */
574  while (IfxMtu_isAutoInitRunning(mbistSel))
575  {}
576 
577  /* Restore the endinit state */
578  if (isEndInitEnabled == 1)
579  {
580  /* Set EndInit Watchdog (to prevent Watchdog TO)*/
581  IfxScuWdt_setSafetyEndinit(password);
582  }
583 
584  return retVal;
585 }
586 
587 
588 static void IfxMtu_waitForMbistDone(uint32 towerDepth, uint8 numInstructions, IfxMtu_MbistSel mbistSel)
589 {
590  uint32 waitFact = (SCU_CCUCON0.B.SPBDIV / SCU_CCUCON0.B.SRIDIV) * numInstructions;
591  volatile uint32 waitTime;
592 
593  switch (mbistSel)
594  {
596  waitFact = waitFact * SCU_CCUCON1.B.GTMDIV;
597  break;
598 
601 
602  break;
603 
606  waitFact = (IfxScuCcu_getSriFrequency() / IfxScuCcu_getPllErayFrequency()) * numInstructions;
607  break;
608 
610  waitFact = (IfxScuCcu_getSriFrequency() / IfxScuCcu_getPllErayFrequency()) * numInstructions;
611  break;
612 
625  waitFact = waitFact * SCU_CCUCON2.B.BBBDIV;
626  break;
627  default:
628  break;
629  }
630 
631  if (numInstructions == 4)
632  {
633  waitTime = (towerDepth * waitFact) + 30;
634  }
635  else
636  {
637  waitTime = ((towerDepth / 4) * waitFact) + 30;
638  }
639 
640  waitTime = waitTime / 3;
641 
642  while (waitTime--)
643  {
644  __nop();
645  }
646 }
647 
648 
649 void IfxMtu_writeSramAddress(IfxMtu_MbistSel mbistSel, uint16 sramAddress)
650 {
651  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
652  uint8 isEndInitEnabled = 0;
653  uint16 password = 0;
655 
656  /* Check if the Endinit is cleared by application. If not, then handle it internally inside teh function.*/
658  {
659  /* Clear EndInit */
661  isEndInitEnabled = 1;
662  }
663 
664  /* configure MBIST for single write opeation */
665  uint16 mcontrolMask = 0x4000; /* set USERED flag */
666  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DIR_OFF);
667  mc->CONFIG0.U = (1 << IFX_MC_CONFIG0_NUMACCS_OFF) | (0 << IFX_MC_CONFIG0_ACCSTYPE_OFF); /* 1 write access */
668  mc->CONFIG1.U = 0; /* ensure that linear scrambling is used */
669 
670  /* Set the address to be written (RAEN = 0) */
671  mc->RANGE.U = sramAddress;
672 
673  /* Start operation */
674  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DIR_OFF) | (1 << IFX_MC_MCONTROL_START_OFF);
675  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DIR_OFF);
676 
677  if (isEndInitEnabled == 1)
678  {
679  /* Set EndInit Watchdog (to prevent Watchdog TO)*/
680  IfxScuWdt_setSafetyEndinit(password);
681  }
682 
683  /* Wait for the end of the operation */
684  IfxMtu_waitForMbistDone(IfxMtu_sramTable[mbistSel].mbistDelay, 1, mbistSel);
685  IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, mc->MSTATUS.B.DONE != 0);
686 
687  while (!IfxMtu_isMbistDone(mbistSel))
688  {
689  __nop();
690  }
691 }