iLLD_TC26x  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 
232  systemAddress = 0x60100000 | ((sramAddress << 4) | ((mbi & 1) << 3));
233  break;
234 
236  systemAddress = 0x60000000 | ((sramAddress << 4) | ((mbi & 3) << 2));
237  break;
238 
239  case IfxMtu_MbistSel_dma:
240  systemAddress = 0xf0012000 | ((sramAddress << 5) | ((mbi & 3) << 3));
241  break;
242 
243  default:
244  systemAddress = 0; /* unsupported address descrambling */
245  }
246 
247  return systemAddress;
248 }
249 
250 
251 uint8 IfxMtu_getTrackedSramAddresses(IfxMtu_MbistSel mbistSel, Ifx_MC_ETRR *trackedSramAddresses)
252 {
253  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
254  uint8 validFlags = (mc->ECCD.U >> IFX_MC_ECCD_VAL_OFF) & IFX_MC_ECCD_VAL_MSK;
255  uint8 numTrackedAddresses = 0;
256  int i;
257 
258 #if IFX_MC_ECCD_VAL_LEN > IFXMTU_MAX_TRACKED_ADDRESSES
259 # error "Unexpected size of VAL mask"
260 #endif
261 
262  for (i = 0; i < IFXMTU_MAX_TRACKED_ADDRESSES; ++i)
263  {
264  if (validFlags & (1 << i))
265  {
266  trackedSramAddresses[numTrackedAddresses].U = mc->ETRR[i].U;
267  ++numTrackedAddresses;
268  }
269  }
270 
271  return numTrackedAddresses;
272 }
273 
274 
276 {
277  volatile uint32 *mtuMemstat = (volatile uint32 *)((uint32)&MTU_MEMSTAT0 + 4 * (mbistSel >> 5));
278  uint32 mask = 1 << (mbistSel & 0x1f);
279  return (*mtuMemstat & mask) != 0;
280 }
281 
282 
284 {
285  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
286  return mc->ECCS.B.TRE ? TRUE : FALSE;
287 }
288 
289 
291 {
292  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
293  return mc->ECCD.B.EOV ? TRUE : FALSE;
294 }
295 
296 
298 {
299  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
300  uint16 status;
301 
302  status = mc->MSTATUS.U;
303  return (boolean)(status & 0x01);
304 }
305 
306 
307 void IfxMtu_readSramAddress(IfxMtu_MbistSel mbistSel, uint16 sramAddress)
308 {
309  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
310 
311  /* configure MBIST for single read opeation */
312  uint16 mcontrolMask = 0x4000; /* set USERED flag */
313  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DIR_OFF);
314  mc->CONFIG0.U = (1 << IFX_MC_CONFIG0_NUMACCS_OFF) | (1 << IFX_MC_CONFIG0_ACCSTYPE_OFF); /* 1 read access */
315  mc->CONFIG1.U = 0; /* ensure that linear scrambling is used */
316 
317  /* Set the address to be read (RAEN = 0) */
318  mc->RANGE.U = sramAddress;
319 
320  /* Start operation */
321  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DIR_OFF) | (1 << IFX_MC_MCONTROL_START_OFF);
322  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DIR_OFF);
323 
324  /* wait for the end of the fill operation */
325  IfxMtu_waitForMbistDone(256, 1, mbistSel);
326 
327  while (!IfxMtu_isMbistDone(mbistSel))
328  {
329  __nop();
330  }
331 }
332 
333 
334 uint8 IfxMtu_runCheckerBoardTest(IfxMtu_MbistSel mbistSel, uint8 rangeSel, uint8 rangeAddrUp, uint8 rangeAddrLow, uint16 *errorAddr, uint32 numberRedundancyLines)
335 {
336  /* Select MBIST Memory Controller:
337  * Ifx_MC is a type describing structure of MBIST Memory Controller
338  * registers defined in IfxMc_regdef.h file - MC object */
339  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
340  uint32 configCheckerBoardSequence[4] = {
341  0x08001000, //up /lin/w0
342  0x08001001, //up /lin/r0
343  0x00011000, //down/lin/w1
344  0x00011001
345  }; //down/lin/r1
346  uint16 password = 0;
347  uint8 retVal = 0U;
348  uint8 testStep;
349  uint8 isEndInitEnabled = 0;
351 
352  /* Check if the Endinit is cleared by application. If not, then handle it internally inside teh function.*/
354  {
355  /* Clear EndInit */
357  isEndInitEnabled = 1;
358  }
359 
360  /* Enable MBIST Memory Controller */
361  IfxMtu_enableMbistShell(mbistSel);
362 
363  /* for auto-init memories: wait for the end of the clear operation */
364  while (IfxMtu_isAutoInitRunning(mbistSel))
365  {}
366 
367  /* Set the range register */
368  mc->RANGE.U = (rangeSel << 15) | (rangeAddrUp << 7) | (rangeAddrLow << 0);
369 
370  /* Run the test */
371  for (testStep = 0; testStep < 4; ++testStep)
372  {
373  mc->CONFIG0.U = configCheckerBoardSequence[testStep] & 0x0000FFFF;
374  mc->CONFIG1.U = (configCheckerBoardSequence[testStep] & 0xFFFF0000) >> 16;
375  mc->MCONTROL.U = numberRedundancyLines ? 0x30c9 : 0x00c9; // bit and row toggle
376  mc->MCONTROL.U = numberRedundancyLines ? 0x30c8 : 0x00c8; // MCONTROL.B.START will generate a RMW which is too long for small SRAMs!
377 
378  /* Set EndInit Watchdog (to prevent Watchdog TO)*/
379  IfxScuWdt_setSafetyEndinit(password);
380 
381  /* wait for the end of the fill operation */
382  IfxMtu_waitForMbistDone(IfxMtu_sramTable[mbistSel].mbistDelay, 4, mbistSel);
383  IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, mc->MSTATUS.B.DONE != 0);
384 
385  while (!IfxMtu_isMbistDone(mbistSel))
386  {
387  __nop();
388  }
389 
390  /* Clear EndInit Again */
392 
393  /* Check the Fail Status */
394  if (mc->MSTATUS.B.FAIL)
395  {
396  /* Test has failed, check if any un-correctable error */
397  if (mc->ECCD.B.UERR)
398  {
399  /* Read Error tracking register and return saying test failed */
400  *errorAddr = mc->ETRR[0].U;
401  retVal = 1U;
402  break;
403  }
404  }
405  }
406 
407  /* Disable Memory Controller */
408 
409  IfxMtu_disableMbistShell(mbistSel);
410 
411  while (IfxMtu_isAutoInitRunning(mbistSel))
412  {}
413 
414  if (isEndInitEnabled == 1)
415  {
416  /* Set EndInit Watchdog (to prevent Watchdog TO)*/
417  IfxScuWdt_setSafetyEndinit(password);
418  }
419 
420  return retVal;
421 }
422 
423 
424 uint8 IfxMtu_runMarchUTest(IfxMtu_MbistSel mbistSel, uint8 rangeSel, uint8 rangeAddrUp, uint8 rangeAddrLow, uint16 *errorAddr)
425 {
426  /* Select MBIST Memory Controller:
427  * Ifx_MC is a type describing structure of MBIST Memory Controller
428  * registers defined in IfxMc_regdef.h file - MC object */
429  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
430  uint32 configMarchUSequence[6] = {
431  0x08001000, //up /lin/w0
432  0x08064005, //up /lin/r0->w1->r1->w0
433  0x08022001, //up /lin/r0->w1
434  0x00094005, //down/lin/r1->w0->r0->w1
435  0x00012001, //down/lin/r1->w0
436  0x00001001
437  }; //down/lin/r0
438  uint16 password = 0;
439  uint8 retVal = 0U;
440  uint8 testStep;
441  uint8 isEndInitEnabled = 0;
443 
444  /* Check if the Endinit is cleared by application. If not, then handle it internally inside teh function.*/
446  {
447  /* Clear EndInit */
449  isEndInitEnabled = 1;
450  }
451 
452  /* Enable MBIST Memory Controller */
453  IfxMtu_enableMbistShell(mbistSel);
454 
455  /* for auto-init memories: wait for the end of the clear operation */
456  while (IfxMtu_isAutoInitRunning(mbistSel))
457  {}
458 
459  /* Set the range register */
460  mc->RANGE.U = (rangeSel << 15) | (rangeAddrUp << 7) | (rangeAddrLow << 0);
461 
462  /* Run the test */
463  for (testStep = 0; testStep < 6; ++testStep)
464  {
465  mc->CONFIG0.U = configMarchUSequence[testStep] & 0x0000FFFF;
466  mc->CONFIG1.U = (configMarchUSequence[testStep] & 0xFFFF0000) >> 16;
467  mc->MCONTROL.U = 0x0209;
468  mc->MCONTROL.B.START = 0;
469 
470  /* Set EndInit Watchdog (to prevent Watchdog TO)*/
471  IfxScuWdt_setSafetyEndinit(password);
472 
473  /* wait for the end of the fill operation */
474  IfxMtu_waitForMbistDone(IfxMtu_sramTable[mbistSel].mbistDelay, 4, mbistSel);
475  IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, mc->MSTATUS.B.DONE != 0);
476 
477  while (!IfxMtu_isMbistDone(mbistSel))
478  {
479  __nop();
480  }
481 
482  /* Clear EndInit Again */
484 
485  /* Check the Fail Status */
486  if (mc->MSTATUS.B.FAIL)
487  {
488  /* Test has failed, check if any un-correctable error */
489  if (mc->ECCD.B.UERR)
490  {
491  /* Read Error tracking register and return saying test failed */
492  *errorAddr = mc->ETRR[0].U;
493  retVal = 1U;
494  break;
495  }
496  }
497  }
498 
499  /* Disable Memory Controller */
500  IfxMtu_disableMbistShell(mbistSel);
501 
502  /* for auto-init memories: wait for the end of the clear operation */
503  while (IfxMtu_isAutoInitRunning(mbistSel))
504  {}
505 
506  /* Restore the endinit state */
507  if (isEndInitEnabled == 1)
508  {
509  /* Set EndInit Watchdog (to prevent Watchdog TO)*/
510  IfxScuWdt_setSafetyEndinit(password);
511  }
512 
513  return retVal;
514 }
515 
516 
517 uint8 IfxMtu_runNonDestructiveInversionTest(IfxMtu_MbistSel mbistSel, uint8 rangeSel, uint8 rangeAddrUp, uint8 rangeAddrLow, uint16 *errorAddr)
518 {
519  /* Select MBIST Memory Controller:
520  * Ifx_MC is a type describing structure of MBIST Memory Controller
521  * registers defined in IfxMc_regdef.h file - MC object */
522  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
523  uint16 password = 0;
524  uint8 retVal = 0U;
525  uint8 isEndInitEnabled = 0;
527 
528  /* Check if the Endinit is cleared by application. If not, then handle it internally inside teh function.*/
530  {
531  /* Clear EndInit */
533  isEndInitEnabled = 1;
534  }
535 
536  /* Enable MBIST Memory Controller */
537  IfxMtu_enableMbistShell(mbistSel);
538 
539  /* for auto-init memories: wait for the end of the clear operation */
540  while (IfxMtu_isAutoInitRunning(mbistSel))
541  {}
542 
543  /* Configure Non-destructive Inversion test */
544  mc->CONFIG0.U = 0x4005; //NUMACCS=4, ACCSTYPE=5
545  mc->CONFIG1.U = 0x5000; //AG_MOD=5
546  /* Set the range register */
547  mc->RANGE.U = (rangeSel << 15) | (rangeAddrUp << 7) | (rangeAddrLow << 0);
548  /* Run the tests */
549  mc->MCONTROL.U = 0xF201;
550  mc->MCONTROL.B.START = 0;
551  /* Set EndInit Watchdog (to prevent Watchdog TO)*/
552  IfxScuWdt_setSafetyEndinit(password);
553 
554  /* wait for the end of the fill operation */
555  IfxMtu_waitForMbistDone(IfxMtu_sramTable[mbistSel].mbistDelay, 4, mbistSel);
556  IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, mc->MSTATUS.B.DONE != 0);
557 
558  while (!IfxMtu_isMbistDone(mbistSel))
559  {
560  __nop();
561  }
562 
563  /* Clear EndInit Again */
565 
566  /* Check the Fail Status */
567  if (mc->MSTATUS.B.FAIL)
568  {
569  /* Test has failed, check if any un-correctable error */
570  if (mc->ECCD.B.UERR)
571  {
572  /* Read the Error tracking register and return saying test failed */
573  *errorAddr = mc->ETRR[0].U;
574  retVal = 1U;
575  }
576  }
577 
578  /* Disable Memory Controller */
579  IfxMtu_disableMbistShell(mbistSel);
580 
581  /* for auto-init memories: wait for the end of the clear operation */
582  while (IfxMtu_isAutoInitRunning(mbistSel))
583  {}
584 
585  /* Restore the endinit state */
586  if (isEndInitEnabled == 1)
587  {
588  /* Set EndInit Watchdog (to prevent Watchdog TO)*/
589  IfxScuWdt_setSafetyEndinit(password);
590  }
591 
592  return retVal;
593 }
594 
595 
596 static void IfxMtu_waitForMbistDone(uint32 towerDepth, uint8 numInstructions, IfxMtu_MbistSel mbistSel)
597 {
598  uint32 waitFact = (SCU_CCUCON0.B.SPBDIV / SCU_CCUCON0.B.SRIDIV) * numInstructions;
599  volatile uint32 waitTime;
600 
601  switch (mbistSel)
602  {
609  waitFact = waitFact * SCU_CCUCON1.B.GTMDIV;
610  break;
612  waitFact = waitFact * SCU_CCUCON1.B.GTMDIV;
613  break;
614 
617  waitFact = waitFact * SCU_CCUCON0.B.BAUD1DIV;
618 
619  break;
620 
623  waitFact = (IfxScuCcu_getSriFrequency() / IfxScuCcu_getPll2ErayFrequency()) * numInstructions;
624  break;
625 
627  waitFact = (IfxScuCcu_getSriFrequency() / IfxScuCcu_getPll2ErayFrequency()) * numInstructions * 4;
628  break;
629 
645  waitFact = waitFact * SCU_CCUCON2.B.BBBDIV;
646  break;
647  default:
648  break;
649  }
650 
651  if (numInstructions == 4)
652  {
653  waitTime = (towerDepth * waitFact) + 30;
654  }
655  else
656  {
657  waitTime = ((towerDepth / 4) * waitFact) + 30;
658  }
659 
660  waitTime = waitTime / 3;
661 
662  while (waitTime--)
663  {
664  __nop();
665  }
666 }
667 
668 
669 void IfxMtu_writeSramAddress(IfxMtu_MbistSel mbistSel, uint16 sramAddress)
670 {
671  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
672  uint8 isEndInitEnabled = 0;
673  uint16 password = 0;
675 
676  /* Check if the Endinit is cleared by application. If not, then handle it internally inside teh function.*/
678  {
679  /* Clear EndInit */
681  isEndInitEnabled = 1;
682  }
683 
684  /* configure MBIST for single write opeation */
685  uint16 mcontrolMask = 0x4000; /* set USERED flag */
686  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DIR_OFF);
687  mc->CONFIG0.U = (1 << IFX_MC_CONFIG0_NUMACCS_OFF) | (0 << IFX_MC_CONFIG0_ACCSTYPE_OFF); /* 1 write access */
688  mc->CONFIG1.U = 0; /* ensure that linear scrambling is used */
689 
690  /* Set the address to be written (RAEN = 0) */
691  mc->RANGE.U = sramAddress;
692 
693  /* Start operation */
694  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DIR_OFF) | (1 << IFX_MC_MCONTROL_START_OFF);
695  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DIR_OFF);
696 
697  if (isEndInitEnabled == 1)
698  {
699  /* Set EndInit Watchdog (to prevent Watchdog TO)*/
700  IfxScuWdt_setSafetyEndinit(password);
701  }
702 
703  /* Wait for the end of the operation */
704  IfxMtu_waitForMbistDone(IfxMtu_sramTable[mbistSel].mbistDelay, 1, mbistSel);
705  IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, mc->MSTATUS.B.DONE != 0);
706 
707  while (!IfxMtu_isMbistDone(mbistSel))
708  {
709  __nop();
710  }
711 }