Energy Micro IEC60355 Library Example Project 1.0 (internal use only!) GCC-Version
Example project demonstrating POST and BIST library functions

RAM Test

The RAM test checks functionality of RAM cells. More...

Collaboration diagram for RAM Test:

Modules

 Library Configuration
 

This modules are prepared for specific devices and compilers.
Changing any of this will cause non or mail functionality and requires new compilation and tests.
Compiler specific issues must be regarded in concern to the user
application. Specific modules have their own configurations to keep
cross effects minimized.

  1. development environment
  2. physical target devices
  3. other internal components and structures like memory size
  4. special conditions (Tessy)

Defines

#define WA(ptr)   * ((volatile uint32_t *) ptr)
#define __st(x)   do { x; } while (0)
#define MOP_R0()   __st(if (WA(ptr) != r0_exp) goto R0_FAULT_DETECTED;)
#define MOP_R1()   __st(if (WA(ptr) != r1_exp) goto R1_FAULT_DETECTED;)
#define MOP_W0()   __st(WA(ptr) = r0_exp;)
#define MOP_W1()   __st(WA(ptr) = r1_exp;)
#define MOP_DEL()   __NOP()
#define TS_STA_RAM_BIST_OK   (0x00B00000UL)
#define TS_STA_RAM_BIST_R0_FAULT   (0x00B10000UL)
#define TS_STA_RAM_BIST_R1_FAULT   (0x00B20000UL)
#define BLOCK_SEL_CORE   0x1
#define BLOCK_SEL_PLINK   0x2
#define initial_sp   (*(uint32_t *) 0x00u)
#define get_initial_sp   (*initial_sp)
#define CORE_RAM_BASE_ADDR   IEC60335_RAM_START
#define CORE_RAM_BASE_PTR   (volatile uint8_t *) CORE_RAM_BASE_ADDR
#define CORE_RAM_MAX_BC   (1024 * 4 * 4)
#define CORE_RAM_R0_EXP   0x0
#define CORE_RAM_R1_EXP   (~CORE_RAM_R0_EXP)
#define PLINK_RAM_BASE_ADDR   (0x40012200UL)
#define PLINK_RAM_BASE_PTR   (volatile uint8_t *) PLINK_RAM_BASE_ADDR
#define PLINK_RAM_MAX_BC   384
#define PLINK_RAM_R0_EXP   0x0
#define PLINK_RAM_R1_EXP   0xFF

Functions

testResult_t IEC60335_ClassB_RAMtest (uint32_t startAddrs, uint32_t size, uint8_t block_sel)
 private function referenced by POST and BIST tests
testResult_t IEC60335_ClassB_RAMtest_POST (void)
 POST public function testing the complete RAM.
testResult_t IEC60335_ClassB_RAMtest_BIST (uint32_t startAddr, uint32_t length)
 BIST public function referenced by BIST tests.

Detailed Description

The RAM test checks functionality of RAM cells.

using the production test of the chip vendor all possible stuck and coupling
effects are tested.

RAM-Test.jpg

Define Documentation

#define __st (   x)    do { x; } while (0)

Definition at line 74 of file iec60335_class_b_ram_test.c.

#define BLOCK_SEL_CORE   0x1
#define BLOCK_SEL_PLINK   0x2

Definition at line 62 of file iec60335_class_b_ram_test.h.

Referenced by IEC60335_ClassB_RAMtest().

#define CORE_RAM_BASE_ADDR   IEC60335_RAM_START

Definition at line 67 of file iec60335_class_b_ram_test.h.

Referenced by IEC60335_ClassB_RAMtest_POST().

#define CORE_RAM_BASE_PTR   (volatile uint8_t *) CORE_RAM_BASE_ADDR

Definition at line 68 of file iec60335_class_b_ram_test.h.

#define CORE_RAM_MAX_BC   (1024 * 4 * 4)

Definition at line 69 of file iec60335_class_b_ram_test.h.

#define CORE_RAM_R0_EXP   0x0

Definition at line 70 of file iec60335_class_b_ram_test.h.

Referenced by IEC60335_ClassB_RAMtest().

#define CORE_RAM_R1_EXP   (~CORE_RAM_R0_EXP)

Definition at line 71 of file iec60335_class_b_ram_test.h.

Referenced by IEC60335_ClassB_RAMtest().

#define get_initial_sp   (*initial_sp)

Definition at line 66 of file iec60335_class_b_ram_test.h.

#define initial_sp   (*(uint32_t *) 0x00u)

Definition at line 65 of file iec60335_class_b_ram_test.h.

Referenced by IEC60335_ClassB_RAMtest().

#define MOP_DEL ( )    __NOP()

Definition at line 81 of file iec60335_class_b_ram_test.c.

Referenced by IEC60335_ClassB_RAMtest().

#define MOP_R0 ( )    __st(if (WA(ptr) != r0_exp) goto R0_FAULT_DETECTED;)

Definition at line 75 of file iec60335_class_b_ram_test.c.

Referenced by IEC60335_ClassB_RAMtest().

#define MOP_R1 ( )    __st(if (WA(ptr) != r1_exp) goto R1_FAULT_DETECTED;)

Definition at line 76 of file iec60335_class_b_ram_test.c.

Referenced by IEC60335_ClassB_RAMtest().

#define MOP_W0 ( )    __st(WA(ptr) = r0_exp;)

Definition at line 79 of file iec60335_class_b_ram_test.c.

Referenced by IEC60335_ClassB_RAMtest().

#define MOP_W1 ( )    __st(WA(ptr) = r1_exp;)

Definition at line 80 of file iec60335_class_b_ram_test.c.

Referenced by IEC60335_ClassB_RAMtest().

#define PLINK_RAM_BASE_ADDR   (0x40012200UL)

Definition at line 72 of file iec60335_class_b_ram_test.h.

Referenced by IEC60335_ClassB_RAMtest().

#define PLINK_RAM_BASE_PTR   (volatile uint8_t *) PLINK_RAM_BASE_ADDR

Definition at line 73 of file iec60335_class_b_ram_test.h.

Referenced by IEC60335_ClassB_RAMtest().

#define PLINK_RAM_MAX_BC   384

Definition at line 74 of file iec60335_class_b_ram_test.h.

Referenced by IEC60335_ClassB_RAMtest().

#define PLINK_RAM_R0_EXP   0x0

Definition at line 75 of file iec60335_class_b_ram_test.h.

Referenced by IEC60335_ClassB_RAMtest().

#define PLINK_RAM_R1_EXP   0xFF

Definition at line 76 of file iec60335_class_b_ram_test.h.

Referenced by IEC60335_ClassB_RAMtest().

#define TS_STA_RAM_BIST_OK   (0x00B00000UL)

Definition at line 57 of file iec60335_class_b_ram_test.h.

#define TS_STA_RAM_BIST_R0_FAULT   (0x00B10000UL)

Definition at line 58 of file iec60335_class_b_ram_test.h.

#define TS_STA_RAM_BIST_R1_FAULT   (0x00B20000UL)

Definition at line 59 of file iec60335_class_b_ram_test.h.

#define WA (   ptr)    * ((volatile uint32_t *) ptr)

Definition at line 61 of file iec60335_class_b_ram_test.c.


Function Documentation

testResult_t IEC60335_ClassB_RAMtest ( uint32_t  startAddrs,
uint32_t  size,
uint8_t  block_sel 
)

private function referenced by POST and BIST tests

Parameters:
startAddrstart address in RAM memory (>0x20000000)
sizesize of RAM to check in bytes (<RAM_MEM_SIZE)
block_selselection of RAM block to check, valid values are BLOCK_SEL_CORE for direct RAM access BLOCK_SEL_PLINK for peripherals (ignoring size and startAddr)
Returns:
passed or failed. See testResult_t . The function allows check in RAM area only. The stack can not be tested here. If an area is tested with stack inside the stack area is excluded. Interrupts during the RAM test may change stack size and corrupt the test.

Definition at line 83 of file iec60335_class_b_ram_test.c.

References BLOCK_SEL_CORE, BLOCK_SEL_PLINK, CORE_RAM_R0_EXP, CORE_RAM_R1_EXP, IEC60335_RAM_SP_Offset, IEC60335_testFailed, IEC60335_testPassed, initial_sp, MOP_DEL, MOP_R0, MOP_R1, MOP_W0, MOP_W1, PLINK_RAM_BASE_ADDR, PLINK_RAM_BASE_PTR, PLINK_RAM_MAX_BC, PLINK_RAM_R0_EXP, and PLINK_RAM_R1_EXP.

Referenced by IEC60335_ClassB_RAMtest_BIST(), and IEC60335_ClassB_RAMtest_POST().

{
  testResult_t result = IEC60335_testFailed;

  /* Note that function calls cannot be used from this function as the */
  /* stack is destroyed. */

  /* Use a byte pointer to increment through the RAM blocks. */
  /* The byte pointer is cast into 32-bit word accesses to generate both */
  /* aligned and unaligned accesses. The unaligned accesses are split into */
  /* multiple 8- and 16-bit accesses by the CM3 bus matrix. That way, we are */
  /* also testing for individual byte WE faults in the RAM IP and address */
  /* decoder faults. */
  register volatile uint8_t *ptr;
  register uint32_t         offset;
  volatile uint8_t          *ram_base_init;
  volatile uint8_t          *ram_end_init;
  register volatile uint8_t *ram_base;
  register volatile uint8_t *ram_end;
  register uint32_t         r0_exp;
  register uint32_t         r1_exp;
  uint32_t                  currentSP;
  register uint32_t         segment_size2;
  uint32_t                  stackSize;

  /* Set RAM block boundary pointers */
  switch (block_sel)
  {
  case BLOCK_SEL_CORE:
    ram_base_init    = (volatile uint8_t *) startAddrs;
    ram_end_init     = ram_base_init + size;
    r0_exp           = CORE_RAM_R0_EXP;
    r1_exp           = CORE_RAM_R1_EXP;
    break;

  case BLOCK_SEL_PLINK:
    ram_base_init    = PLINK_RAM_BASE_PTR;
    ram_end_init     = (volatile uint8_t *)(PLINK_RAM_BASE_ADDR + PLINK_RAM_MAX_BC);
    r0_exp           = PLINK_RAM_R0_EXP;
    r1_exp           = PLINK_RAM_R1_EXP;
    CMU->HFPERCLKEN0 = ~0;
    break;

  default:
    goto BOUNDARY_FAULT_DETECT;                               /* error condition */
    break;
  }
  do {
    segment_size2    = 0;
    if (block_sel == BLOCK_SEL_CORE)
    {
      currentSP = getSP();
      stackSize = initial_sp - currentSP;
      
      /* test boundaries */
      if (((uint32_t)ram_base_init < RAM_MEM_BASE)||((uint32_t)ram_end_init > (RAM_MEM_BASE + RAM_MEM_SIZE)))
      {
        goto BOUNDARY_FAULT_DETECT;
      }
      if (ram_base_init > ram_end_init)
      {
        goto BOUNDARY_FAULT_DETECT;
      }
      if ((currentSP < RAM_MEM_BASE)||(currentSP > initial_sp)||(stackSize > RAM_MEM_SIZE))
      {
        goto BOUNDARY_FAULT_DETECT;
      }
      if ((size%4 != 0) || (size == 0))
      {
        goto BOUNDARY_FAULT_DETECT;
      }

      /* check stack end in tested RAM area */
      if ((currentSP > (uint32_t) ram_base_init) && (currentSP < (uint32_t) ram_end_init))
      {
        /* check SP at end of tested RAM section */
        if (initial_sp >= ((uint32_t)ram_end_init - 0x10))
        {
          /* stack is at the end of the tested area */
          ram_end_init = (uint8_t*)(currentSP - IEC60335_RAM_SP_Offset);
          segment_size2 = 0;
          /* check sufficient size of tested memory */
          if (ram_base_init >= ram_end_init)
          {
            goto BOUNDARY_FAULT_DETECT;
          }
        }
        else /* there is a gap behind the stack */
        {
          segment_size2 = (uint32_t)ram_end_init - initial_sp;    /* next segment to check */
          ram_end_init = (uint8_t*)(currentSP - IEC60335_RAM_SP_Offset);
        }
      }
      /* check stack start in tested RAM area */
      else if ((initial_sp > (uint32_t) ram_base_init) && (initial_sp < (uint32_t) ram_end_init))
      {
        /* stack is at the start of the tested area */
        ram_base_init = (uint8_t*)initial_sp + 4;
        segment_size2 = 0;
        /* check sufficient size of tested memory */
        if (ram_base_init >= ram_end_init)
        {
          goto BOUNDARY_FAULT_DETECT;
        }
      }
    }
    for (offset = 0; offset < sizeof(uint32_t); offset++)
    {
      /* Offset the byte boundary pointer to generate all combinations of aligned and unaligned access to the Core RAM. */
      /* The PLINK RAM is arranged as bytes aligned to 32-bit word addresses. Hence, skip offset 1, 2 and 3 for the PLINK RAM. */
      if (offset != 0)
      {
        if (block_sel != BLOCK_SEL_CORE)
          break;
        ram_base = (volatile uint8_t *)((uint32_t) ram_base_init + offset);
        ram_end  = (volatile uint8_t *)((uint32_t) ram_end_init + offset - sizeof(uint32_t));       /* do not exceed the last byte on unaligned access */
      }
      else
      {
        ram_base = ram_base_init;
        ram_end  = ram_end_init;
      }

      /* March element M0: <->(w0), using -> address order */
      ptr = ram_base;
      while (ptr < ram_end)
      {
        MOP_W0();
        ptr = ptr + sizeof(uint32_t);
      }

      /* March element M1: ->(r0,w1) */
      ptr = ram_base;
      while (ptr < ram_end)
      {
        MOP_R0();
        MOP_W1();
        ptr = ptr + sizeof(uint32_t);
      }

      /* March element M2: <-(r1,w0,r0,w1) */
      ptr = (ram_end - sizeof(uint32_t));
      while (ptr >= ram_base)
      {
        MOP_R1();
        MOP_W0();
        MOP_R0();
        MOP_W1();
        ptr = ptr - sizeof(uint32_t);
      }

      /* March element M3: <-(r1,w0) */
      ptr = (ram_end - sizeof(uint32_t));
      while (ptr >= ram_base)
      {
        MOP_R1();
        MOP_W0();
        ptr = ptr - sizeof(uint32_t);
      }

      /* March element M4: <-(r0,w1,r1,w0) */
      ptr = (ram_end - sizeof(uint32_t));
      while (ptr >= ram_base)
      {
        MOP_R0();
        MOP_W1();
        MOP_R1();
        MOP_W0();
        ptr = ptr - sizeof(uint32_t);
      }

      /* March element M5: <-(r0) */
      ptr = (ram_end - sizeof(uint32_t));
      while (ptr >= ram_base)
      {
        MOP_R0();
        ptr = ptr - sizeof(uint32_t);
      }

      /* March element M6: Del */
      MOP_DEL();

      /* March element M7: <->(r0,w1,r1), using -> address order */
      ptr = ram_base;
      while (ptr < ram_end)
      {
        MOP_R0();
        MOP_W1();
        MOP_R1();
        ptr = ptr + sizeof(uint32_t);
      }

      /* March element M8: Del */
      MOP_DEL();

      /* March element M9: <->(r1), using <- address order */
      ptr = (ram_end - sizeof(uint32_t));
      while (ptr >= ram_base)
      {
        MOP_R1();
        ptr = ptr - sizeof(uint32_t);
      }
    }
    if (segment_size2 != 0)
    {
      ram_base_init = (volatile uint8_t *) initial_sp + 4;
      ram_end_init  = (volatile uint8_t *) initial_sp + segment_size2;
    }
  } while (segment_size2);
  /* No faults found, report OK */
  result = IEC60335_testPassed;
  goto RAM_TEST_END;

 /* Fault return */
 BOUNDARY_FAULT_DETECT:
  result = IEC60335_testFailed;
  goto RAM_TEST_END;

 R0_FAULT_DETECTED:
  result = IEC60335_testFailed;
  goto RAM_TEST_END;

 R1_FAULT_DETECTED:
  result = IEC60335_testFailed;

 RAM_TEST_END:
  return(result);
}

Here is the caller graph for this function:

testResult_t IEC60335_ClassB_RAMtest_BIST ( uint32_t  startAddr,
uint32_t  length 
)

BIST public function referenced by BIST tests.

Parameters:
startAddrstart address in RAM
lengthlength of RAM to check in Bytes
Returns:
passed or failed. See testResult_t .
RAM-Test_BIST.jpg
The stack area is excluded from this test.

Definition at line 317 of file iec60335_class_b_ram_test.c.

References BLOCK_SEL_CORE, IEC60335_ClassB_RAMtest(), IEC60335_RAM_buffersize, IEC60335_RAM_SIZE, IEC60335_RAM_START, IEC60335_testFailed, and util_memcpy().

Referenced by main().

{
  uint8_t      buffer[IEC60335_RAM_buffersize];
  testResult_t result = IEC60335_testFailed;

/* check StartAddr in RAM space */
  if (startAddr > (IEC60335_RAM_START + IEC60335_RAM_SIZE - 4))
  {
    return(result);
  }
  if (startAddr < IEC60335_RAM_START)
  {
    return(result);
  }
/* limit size to buffer size */
  if (length > IEC60335_RAM_buffersize)
  {
    length = IEC60335_RAM_buffersize;
  }
  if (length == 0) 
  {
    return(result);
  }
/* limit endaddress to RAM space */
  if ((startAddr + length) > (IEC60335_RAM_START + IEC60335_RAM_SIZE - 4))
  {
    length = IEC60335_RAM_START + IEC60335_RAM_SIZE - 4 - startAddr;
  }
/* check buffer overlaps test area low */
  if (((uint32_t) &buffer[0] > startAddr) && ((uint32_t) &buffer[0] < (startAddr + length)))
  {
    return(result);
  }
/* check buffer overlaps test area high */
  if (((uint32_t) &buffer[IEC60335_RAM_buffersize - 1] > startAddr) && 
      ((uint32_t) &buffer[IEC60335_RAM_buffersize - 1] < (startAddr + length)))
  {
    return(result);
  }
/* save memory content */
  util_memcpy(&buffer[0], &startAddr, length);

  result = IEC60335_ClassB_RAMtest(startAddr, length, BLOCK_SEL_CORE);
/* restore memory content */
  util_memcpy(&startAddr, &buffer[0], length);
  return(result);
}

Here is the call graph for this function:

Here is the caller graph for this function:

testResult_t IEC60335_ClassB_RAMtest_POST ( void  )

POST public function testing the complete RAM.

Returns:
passed or failed. See testResult_t . The function calls IEC60335_ClassB_RAMtest() with all available RAM memory as parameter. The stack area is excluded from this test in fact there is no relevant stack depth expected at the POST test.

Definition at line 312 of file iec60335_class_b_ram_test.c.

References BLOCK_SEL_CORE, CORE_RAM_BASE_ADDR, IEC60335_ClassB_RAMtest(), and IEC60335_RAM_SIZE.

Referenced by IEC60335_ClassB_POST().

Here is the call graph for this function:

Here is the caller graph for this function: