![]() |
Energy Micro IEC60355 Library Example Project 1.0 (internal use only!) GCC-Version
Example project demonstrating POST and BIST library functions
|
The RAM test checks functionality of RAM cells. More...
|
Modules | |
| Library Configuration | |
This modules are prepared for specific devices and compilers.
| |
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. | |
The RAM test checks functionality of RAM cells.
using the production test of the chip vendor all possible stuck and coupling
effects are tested.
| #define __st | ( | x | ) | do { x; } while (0) |
Definition at line 74 of file iec60335_class_b_ram_test.c.
| #define BLOCK_SEL_CORE 0x1 |
Definition at line 61 of file iec60335_class_b_ram_test.h.
Referenced by IEC60335_ClassB_RAMtest(), IEC60335_ClassB_RAMtest_BIST(), and IEC60335_ClassB_RAMtest_POST().
| #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.
| testResult_t IEC60335_ClassB_RAMtest | ( | uint32_t | startAddrs, |
| uint32_t | size, | ||
| uint8_t | block_sel | ||
| ) |
private function referenced by POST and BIST tests
| startAddr | start address in RAM memory (>0x20000000) |
| size | size of RAM to check in bytes (<RAM_MEM_SIZE) |
| block_sel | selection of RAM block to check, valid values are BLOCK_SEL_CORE for direct RAM access BLOCK_SEL_PLINK for peripherals (ignoring size and startAddr) |
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);
}

| testResult_t IEC60335_ClassB_RAMtest_BIST | ( | uint32_t | startAddr, |
| uint32_t | length | ||
| ) |
BIST public function referenced by BIST tests.
| startAddr | start address in RAM |
| length | length of RAM to check in Bytes |
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);
}


| testResult_t IEC60335_ClassB_RAMtest_POST | ( | void | ) |
POST public function testing the complete RAM.
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().
{
return ((testResult_t)IEC60335_ClassB_RAMtest(CORE_RAM_BASE_ADDR, IEC60335_RAM_SIZE, BLOCK_SEL_CORE));
}

