PSoC5LP: Using SRAM test functions from AN78175

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
KyTr_1955226
Level 6
Level 6
250 sign-ins 10 likes given 50 solutions authored

Hello!

I'm trying to implement a few of the Self-Test functions from AN78175 into an existing project that requires testing of the SRAM at runtime.

I started with the workspace included in AN78175.  After removing the custom linker script which was calling out a non-existent "micro-names.inc" include file (see here), the project compiled just fine for a CY8CKIT-050 and the SelfTests_SRAM_March() and SelfTests_SRAM_Checkerboard() functions appear to work fine and the SRAM checks out as OK.

Where I'm running into a problem is using the Self Test SRAM functions in my own project for a CY8C5667AXI-LP040.  Using the example project code as a guide, I created tests for both Flash (using ECC, seems to work OK) and a SRAM test function, which is what I'm having an issue with:

 

bool Perform_SRAMTest (void){
    uint16_t init_marchcounter = 0;
    uint8_t result;
    /* Initialize RAM base address for checkerboard test */
    SelfTests_Init_SRAM_Test();

    /* Initialize RAM base address for March test */
    SelfTests_Init_March_SRAM_Test();

    /***************************************/
    /* Run March RAM Self-test */
    /***************************************/
    /* Wait for end of SRAM test */
    result = SelfTests_SRAM_March();
    printf("R:%d\r\n",result);
    init_marchcounter++;
    while((result != PASS_COMPLETE_STATUS) && (init_marchcounter != NUMBERS_OF_TEST_CYCLES))
    {
        result = SelfTests_SRAM_March();
        printf("R:%d\r\n",result);
        init_marchcounter++;
    }

    if(init_marchcounter == NUMBERS_OF_TEST_CYCLES)
    {
        /*error*/
        DBG_UART_PutString("SRAM MARCH ERROR\r\n");
        return true;
    } else {
        DBG_UART_PutString("SRAM MARCH PASS\r\n");
        return false;
    }

}

 

This should be functionally identical to the example project, but with some printf() calls to track the result of each call of SelfTests_SRAM_March(); I am finding that every call results in a result of 1.  I have also tried using SelfTests_SRAM_Checkerboard(WORDS_IN_BLOCK); but that also returns error status.

So unless the SRAM in this part is bad (unlikely) I must have done something wrong, or maybe I need to adjust something for the change in part from a CY8C5868AXI-LP035 to a CY8C5667AXI-LP040?  What might I be missing here? 

I have made and attached a test project that exhibits the problem for CY8C5667AXI-LP040.  It performs a SRAM test and a FLASH test using ECC  and spits the result out via UART. There's only a few components (a few IO pins, a timer, and a status register).  It at least tells me that it's probably unrelated to any of my code in the large project.

Any tips would be greatly appreciated!

 

0 Likes
1 Solution
KyTr_1955226
Level 6
Level 6
250 sign-ins 10 likes given 50 solutions authored

Well I found some addresses in the project that didn't line up with the .map file and cydevice.h.  Going to go over them one by one.

First, the stack.  The original starting address for the stack is defined as:

 

/* Start address of Stack */
.equ CYDEV_STACK_BASE_H, 0x2000
.equ CYDEV_STACK_BASE_L, 0x7800 


/* End address of Stack */
.equ END_STACK_ADDR_H, 0x2000  
.equ END_STACK_ADDR_L, 0x8000   

 

Looking in the .map file for the actual build, this did not match the actual placement:

 

.stack          0x20003800      0x800
                0x20003800                __cy_stack_limit = .
                0x20004000                . = (. + 0x800)

 

According to the map file, I should be setting up at 0x20003800-0x20004000 like so:

 

/* Start address of Stack */
.equ CYDEV_STACK_BASE_H, 0x2000
.equ CYDEV_STACK_BASE_L, 0x3800 


/* End address of Stack */
.equ END_STACK_ADDR_H, 0x2000  
.equ END_STACK_ADDR_L, 0x4000   

 

I also looked into the other addresses.  Next is the SRAM Base Address:

 

/* Address of SRAM base */
.equ CYDEV_SRAM_BASE_H, 0x1fff
.equ CYDEV_SRAM_BASE_L, 0x8000

 

Looking in cydevice.h, this did not line up with the actual SRAM starting address of the device:

 

#define CYDEV_SRAM_BASE 0x1fffc000u
#define CYDEV_SRAM_SIZE 0x00008000u

 

 So I changed the SRAM Base Address to match cydevice.h:

 

/* Address of SRAM base */
.equ CYDEV_SRAM_BASE_H, 0x1fff
.equ CYDEV_SRAM_BASE_L, 0xC000

 

With this change made, the SRAM testing area also needed to change, since our ending address of SRAM is not 0x20007800 as it is in the original project, but is 0x20004000 going by cydevice.h:

(CYDEV_SRAM BASE + CYDEV_SRAM_SIZE)

(0x1FFFC000 + 0x00008000) = 0x20004000

The reserved SRAM must be at the end of the SRAM, but since that's where the stack is, I'm figuring I need to place just before the stack.  That would put the reserved section at 0x20003400-0x20003800.

So I adjusted the reserved SRAM section:

 

/* Block size in SRAM test */
.equ BLOCK_SIZE_BYTE, 0x0400 

/* Reserved part of SRAM used for RAM data storing during the March test. */
/* Reserved area is 0x20007000 - 0x20007400.                              */
.equ START_BUFF_ADDR_H, 0x2000 
.equ START_BUFF_ADDR_L, 0x7000

.equ END_BUFF_ADDR_H, 0x2000  
.equ END_BUFF_ADDR_L, 0x7400   

 

After these changes, the march test now passes in my test project.  All told it looks like I just had to adjust the SRAM addresses to match the changes in SRAM between devices (for some reason I thought this was an automated thing and it would utilize the generated constants from cydevice.h).  Now hopefully porting this over to my actual project will be a smooth endeavor.

View solution in original post

0 Likes
6 Replies
DheerajK_81
Moderator
Moderator
Moderator
First comment on KBA First comment on blog 5 questions asked

Hello @KyTr_1955226 ,

Did you try debugging to see where exactly the code might be failing? There are multiple points from where the error_detected might come from in the SelfTest_SRAM_March.s file. Please try to find out exact point of failure here, it will give us more insight on the issue. I checked the two devices and technically it should work for both since there is only a minor difference. 

Any other modifications you did apart from the removal of the linker script? 

You could try to do a swap test to see if that solves the problem too. 

Regards,
Dheeraj

0 Likes

Hi Dheeraj,

Appreciate the reply.  I wasn't sure if running the debugger was appropriate when doing a RAM test, but I gave it a shot.  Unfortunately it has been a very long time (since university I think) since I've had to try and parse out ASM, so my takeaways will probably be very limited.  I ran the SRAM_Test project from my first post, with no modification to the code.

It looks like the March Test fails on the very first section, where it is testing the area of SRAM that is supposed to be reserved for use by the test (0x20007400 - 0x20007800).

 /* Test reserved RAM area. This is 0x20007400 - 0x20007800 in current example */
bl March_Test_Block

/* Check result of reserved RAM testing */
cmp r7, #0
bne Error_detected

I ran this using the debugger a few times.  It failed on the first compare and branches to Error_detected  every time I have run it.  Here's the registers when I break on the cmp:

KyTr_1955226_1-1624645663522.png

Digging deeper, I find the error is detected after it finishes writing all 0x00, and attempts to read back the 0x00 and write 0xFF inside March_Test_Read0_Write1_Inc.  It looks like it fails on the very first byte it checks.  Looking for 0x00 at 0x20007400, it finds 0xFF in Register r9.

March_Test_Read0_Write1_Inc:

/* Write address of first tested byte in r8 */
/* r8 - pointer to current tested byte in RAM */
mov r8, r0

IRAM_chk2:

/* Write byte of SRAM to r9 */
LDRB r9, [r8]

/* Compare content of byte in SRAM with 0x00 */
cmp r9, #0 /*<----Breakpoint here confirms r9 contains 0xFF instead of 0x00. Test fails.*/

Trying to look at the actual region of SRAM it is testing in the memory debug window, I don't get anything helpful.  Maybe I'm not looking in the right spot?  Is the memory view address absolute or relative?

KyTr_1955226_0-1624644827757.png

Maybe I just need to wait for a while, since it looks like the Memory window reads and updates sequentially.  Might need to wait for it to catch up?

I did not perform any modifications other than removing the linker file.  The source code of the RAM test library is untouched.

Again, very much appreciate the help on this!

 

0 Likes
KyTr_1955226
Level 6
Level 6
250 sign-ins 10 likes given 50 solutions authored

Bumping so this doesn't get auto-locked or anything.  Still no clue why this is failing.

0 Likes
KyTr_1955226
Level 6
Level 6
250 sign-ins 10 likes given 50 solutions authored

Today I took some time to step through the "Checkerboard" variant of RAM test.  The checkerboard test also fails right away exactly like the March test.

First thing I noticed is the starting SRAM byte may not be within the proper range?  The code enters SelfTests_SRAM_Checkerboard() and looks like it may be adjusting the byte address?

/* Check if SRAM byte address is not out of SRAM range */
if(Sram_TestByte < (uint32)(CYDEV_SRAM_BASE + PSOC_SRAM_SHIFT))
{
    Sram_TestByte = (uint32)(CYDEV_SRAM_BASE + PSOC_SRAM_SHIFT);  //<---We are getting here
} 

 

We eventually come to a call of SelfTest_SRAM_Byte().  It fails on the first byte tested:

/* Read data on address which contains Sram_TestByte variable */
/* and compare with CHECKERBOARD_PATTERN_55 */
if(CY_GET_REG8(Sram_TestByte) != CHECKERBOARD_PATTERN_55)
{
    /* Restore saved value to address which contains Sram_TestByte variable */
    CY_SET_REG8(Sram_TestByte, RegValue);
    ret = ERROR_STATUS;
} 

 

I keep thinking that maybe it's not actually testing a location inside the device SRAM.  But the macros it uses for PSOC_SRAM_SIZE and PSOC_SRAM_BASE, which from my understanding determine the address where we start and end the test, come from CYDEV_SRAM_SIZE and CYDEV_SRAM_BASE, which should be auto-generated.  So unless there's a problem with the auto-generated cydevice.h macros I still don't understand what the problem could be?

0 Likes
KyTr_1955226
Level 6
Level 6
250 sign-ins 10 likes given 50 solutions authored

Bumping again.

 

The rest of this project is nearly done, but this SRAM test is still a thorn keeping it from the finish line.  Anyone out there that can even reproduce this maybe?

0 Likes
KyTr_1955226
Level 6
Level 6
250 sign-ins 10 likes given 50 solutions authored

Well I found some addresses in the project that didn't line up with the .map file and cydevice.h.  Going to go over them one by one.

First, the stack.  The original starting address for the stack is defined as:

 

/* Start address of Stack */
.equ CYDEV_STACK_BASE_H, 0x2000
.equ CYDEV_STACK_BASE_L, 0x7800 


/* End address of Stack */
.equ END_STACK_ADDR_H, 0x2000  
.equ END_STACK_ADDR_L, 0x8000   

 

Looking in the .map file for the actual build, this did not match the actual placement:

 

.stack          0x20003800      0x800
                0x20003800                __cy_stack_limit = .
                0x20004000                . = (. + 0x800)

 

According to the map file, I should be setting up at 0x20003800-0x20004000 like so:

 

/* Start address of Stack */
.equ CYDEV_STACK_BASE_H, 0x2000
.equ CYDEV_STACK_BASE_L, 0x3800 


/* End address of Stack */
.equ END_STACK_ADDR_H, 0x2000  
.equ END_STACK_ADDR_L, 0x4000   

 

I also looked into the other addresses.  Next is the SRAM Base Address:

 

/* Address of SRAM base */
.equ CYDEV_SRAM_BASE_H, 0x1fff
.equ CYDEV_SRAM_BASE_L, 0x8000

 

Looking in cydevice.h, this did not line up with the actual SRAM starting address of the device:

 

#define CYDEV_SRAM_BASE 0x1fffc000u
#define CYDEV_SRAM_SIZE 0x00008000u

 

 So I changed the SRAM Base Address to match cydevice.h:

 

/* Address of SRAM base */
.equ CYDEV_SRAM_BASE_H, 0x1fff
.equ CYDEV_SRAM_BASE_L, 0xC000

 

With this change made, the SRAM testing area also needed to change, since our ending address of SRAM is not 0x20007800 as it is in the original project, but is 0x20004000 going by cydevice.h:

(CYDEV_SRAM BASE + CYDEV_SRAM_SIZE)

(0x1FFFC000 + 0x00008000) = 0x20004000

The reserved SRAM must be at the end of the SRAM, but since that's where the stack is, I'm figuring I need to place just before the stack.  That would put the reserved section at 0x20003400-0x20003800.

So I adjusted the reserved SRAM section:

 

/* Block size in SRAM test */
.equ BLOCK_SIZE_BYTE, 0x0400 

/* Reserved part of SRAM used for RAM data storing during the March test. */
/* Reserved area is 0x20007000 - 0x20007400.                              */
.equ START_BUFF_ADDR_H, 0x2000 
.equ START_BUFF_ADDR_L, 0x7000

.equ END_BUFF_ADDR_H, 0x2000  
.equ END_BUFF_ADDR_L, 0x7400   

 

After these changes, the march test now passes in my test project.  All told it looks like I just had to adjust the SRAM addresses to match the changes in SRAM between devices (for some reason I thought this was an automated thing and it would utilize the generated constants from cydevice.h).  Now hopefully porting this over to my actual project will be a smooth endeavor.

0 Likes