1467 views|1 replies

410

Posts

3

Resources
The OP
 

【HC32F4A0 development board】External SDRAM memory read and write test [Copy link]

 

This article will learn the read and write test of the SDRAM memory on the board. Store a piece of data and read it out, and print it out on the serial port.

1. Hardware circuit

The board uses the IS42S16400 chip

2. Program part

2.1、sdram.c

#include "main.h"


#define DATA_BUF_LEN                    (0x8000UL)


#define SMC_SDRAM_ADDR    ((uint32_t)(0x80000000))	
uint32_t testsdram[10000] __attribute__((at(0X80000000)));

uint32_t m_u32StartAddr = 0UL;
uint32_t m_u32ByteSize = 0UL;

uint8_t m_au8ReadData[DATA_BUF_LEN];
uint8_t m_au8WriteData[DATA_BUF_LEN];

uint16_t m_au16ReadData[DATA_BUF_LEN];
uint16_t m_au16WriteData[DATA_BUF_LEN];

uint32_t m_au32ReadData[DATA_BUF_LEN];
uint32_t m_au32WriteData[DATA_BUF_LEN];

uint32_t m_u32TestCnt = 0UL;
uint32_t m_u32ByteTestErrorCnt = 0UL;
uint32_t m_u32HalfwordTestErrorCnt = 0UL;
uint32_t m_u32WordTestErrorCnt = 0UL;






void sdram_read_volume(void)
{
	BSP_IS42S16400J7TLI_GetMemInfo(&m_u32StartAddr, &m_u32ByteSize);
	DDL_Printf("Memory start address: 0x%.8x \r\n", (unsigned int)m_u32StartAddr);
	DDL_Printf("Memory end   address: 0x%.8x \r\n", (unsigned int)(m_u32StartAddr + m_u32ByteSize - 1UL));
	DDL_Printf("Memory size  (Bytes): 0x%.8x \r\n\r\n", (unsigned int)m_u32ByteSize);
}

void init_sdram(void)
{
	BSP_IS42S16400J7TLI_Init();
	sdram_read_volume();
	
}



/**
 * [url=home.php?mod=space&uid=159083]@brief[/url] Initialize test data.
 * @param  None
 * @retval None
 */
static void InitTestData(void)
{
    uint32_t i;

    /* Clear count value */
    m_u32ByteTestErrorCnt = 0UL;
    m_u32HalfwordTestErrorCnt = 0UL;
    m_u32WordTestErrorCnt = 0UL;

    /* Initialize test data. */
    for (i = 0UL; i < DATA_BUF_LEN; i++) {
        m_au8ReadData[i] = 0U;
        m_au16ReadData[i] = 0U;
        m_au32ReadData[i] = 0UL;
        m_au8WriteData[i] = (uint8_t)rand();
        m_au16WriteData[i] = (uint16_t)rand();
        m_au32WriteData[i] = (uint32_t)rand();
    }
}

/**
 * @brief  Write memory for byte.
 * @param  [in] u32Addr                 Memory address to write
 * @param  [in] au8Data                 Pointer to source buffer
 * @param  [in] u32Len                  Length of the buffer to write to memory
 * @retval int32_t:
 *           - LL_OK:                   Write successfully.
 *           - LL_ERR_INVD_PARAM:       If one of following cases matches:
 *                                      -The pointer au8Data value is NULL.
 *                                      -The variable u32Len value is 0.
 */
static int32_t MEMORY_Write8(uint32_t u32Addr, const uint8_t au8Data[], uint32_t u32Len)
{
    uint32_t i;
    int32_t i32Ret = LL_ERR_INVD_PARAM;

    if ((au8Data != NULL) && (0UL != u32Len)) {
        for (i = 0UL; i < u32Len; i++) {
            *(uint8_t *)(u32Addr + i) = au8Data[i];
        }
        i32Ret = LL_OK;
    }

    return i32Ret;
}

/**
 * @brief  Read memory for byte.
 * @param  [in] u32Addr                 Memory address to read
 * @param  [out] au8Data                Pointer to buffer
 * @param  [in] u32Len                  Length of the buffer to read from memory
 * @retval int32_t:
 *           - LL_OK:                   Read successfully.
 *           - LL_ERR_INVD_PARAM:       If one of following cases matches:
 *                                      -The pointer au8Data value is NULL.
 *                                      -The variable u32Len value is 0.
 */
static int32_t MEMORY_Read8(uint32_t u32Addr, uint8_t au8Data[], uint32_t u32Len)
{
    uint32_t i;
    int32_t i32Ret = LL_ERR_INVD_PARAM;

    if ((NULL != au8Data) && (0UL != u32Len)) {
        for (i = 0UL; i < u32Len; i++) {
            au8Data[i] = *(uint8_t *)(u32Addr + i);
        }
        i32Ret = LL_OK;
    }

    return i32Ret;
}

/**
 * @brief  Write memory for half-word.
 * @param  [in] u32Addr                 Memory address to write
 * @param  [in] au16Data                Pointer to buffer
 * @param  [in] u32Len                  Length of the buffer to write to memory
 * @retval int32_t:
 *           - LL_OK:                   Write successfully.
 *           - LL_ERR_INVD_PARAM:       If one of following cases matches:
 *                                      -The pointer au16Data value is NULL.
 *                                      -The variable u32Len value is 0.
 */
static int32_t MEMORY_Write16(uint32_t u32Addr, const uint16_t au16Data[], uint32_t u32Len)
{
    uint32_t i;
    int32_t i32Ret = LL_ERR_INVD_PARAM;

    if ((au16Data != NULL) && (0UL != u32Len)) {
        for (i = 0UL; i < u32Len; i++) {
            *((uint16_t *)u32Addr) = au16Data[i];
            u32Addr += 2UL;
        }
        i32Ret = LL_OK;
    }

    return i32Ret;
}

/**
 * @brief  Read memory for half-word.
 * @param  [in] u32Addr                 Memory address to read
 * @param  [out] au16Data               Pointer to buffer
 * @param  [in] u32Len                  Length of the buffer to read from memory
 * @retval int32_t:
 *           - LL_OK:                   Read successfully.
 *           - LL_ERR_INVD_PARAM:       If one of following cases matches:
 *                                      -The pointer au16Data value is NULL.
 *                                      -The variable u32Len value is 0.
 */
static int32_t MEMORY_Read16(uint32_t u32Addr, uint16_t au16Data[], uint32_t u32Len)
{
    uint32_t i;
    int32_t i32Ret = LL_ERR_INVD_PARAM;

    if ((NULL != au16Data) && (0UL != u32Len)) {
        for (i = 0UL; i < u32Len; i++) {
            au16Data[i] = *((uint16_t *)u32Addr);
            u32Addr += 2UL;
        }
        i32Ret = LL_OK;
    }

    return i32Ret;
}

/**
 * @brief  Write memory for word.
 * @param  [in] u32Addr                 Memory address to write
 * @param  [in] au32Data                Pointer to source buffer
 * @param  [in] u32Len                  Length of the buffer to write to memory
 * @retval int32_t:
 *           - LL_OK:                   Read successfully.
 *           - LL_ERR_INVD_PARAM:       If one of following cases matches:
 *                                      -The pointer au32Data value is NULL.
 *                                      -The variable u32Len value is 0.
 */
static int32_t MEMORY_Write32(uint32_t u32Addr, const uint32_t au32Data[], uint32_t u32Len)
{
    uint32_t i;
    int32_t i32Ret = LL_ERR_INVD_PARAM;

    if ((NULL != au32Data) && (0UL != u32Len)) {
        for (i = 0UL; i < u32Len; i++) {
            *((uint32_t *)u32Addr) = au32Data[i];
            u32Addr += 4UL;
        }
        i32Ret = LL_OK;
    }

    return i32Ret;
}

/**
 * @brief  Read memory for word.
 * @param  [in] u32Addr                 Memory address to read
 * @param  [out] au32Data               Pointer to destination buffer to write
 * @param  [in] u32Len                  Length of the buffer to read from memory
 * @retval int32_t:
 *           - LL_OK:                   Read successfully.
 *           - LL_ERR_INVD_PARAM:       If one of following cases matches:
 *                                      -The pointer au32Data value is NULL.
 *                                      -The variable u32Len value is 0.
 */
static int32_t MEMORY_Read32(uint32_t u32Addr, uint32_t au32Data[], uint32_t u32Len)
{
    uint32_t i;
    int32_t i32Ret = LL_ERR_INVD_PARAM;

    if ((NULL != au32Data) && (0UL != u32Len)) {
        for (i = 0UL; i < u32Len; i++) {
            au32Data[i] = *((uint32_t *)u32Addr);
            u32Addr += 4UL;
        }
        i32Ret = LL_OK;
    }

    return i32Ret;
}

/**
 * @brief  Access memory for byte.
 * @param  [in] u3AccessAddr:           Memory address
 * @param  [in] NumBytes:               Access size(unit: byte)
 * @retval count for reading and writing dada error
 */
static uint32_t MEMORY_Access8(uint32_t u3AccessAddr, uint32_t NumBytes)
{
    uint32_t i;
    uint32_t j;
    uint32_t u32TestErrCnt = 0UL;
    uint32_t u32MemoryAddr = u3AccessAddr;

    for (i = 0UL; i < NumBytes; i += DATA_BUF_LEN) {
        (void)MEMORY_Write8(u32MemoryAddr, m_au8WriteData, DATA_BUF_LEN);
        (void)MEMORY_Read8(u32MemoryAddr, m_au8ReadData, DATA_BUF_LEN);

        /* Verify data. */
        for (j = 0UL; j < DATA_BUF_LEN; j++) {
            if (m_au8WriteData[j] != m_au8ReadData[j]) {
                u32TestErrCnt++;
                DDL_Printf("Byte read/write error: address = 0x%.8x; write data = 0x%x; read data = 0x%x\r\n",
                           (unsigned int)(u32MemoryAddr + j), (unsigned int)m_au8WriteData[j], (unsigned int)m_au8ReadData[j]);
            }
        }

        u32MemoryAddr += (DATA_BUF_LEN * sizeof(m_au8ReadData[0]));
        (void)memset(m_au8ReadData, 0, (DATA_BUF_LEN * sizeof(m_au8ReadData[0])));
        BSP_LED_Toggle(LED_BLUE);
    }

    return u32TestErrCnt;
}

/**
 * @brief  Access memory for half-word.
 * @param  [in] u3AccessAddr:           Memory address
 * @param  [in] NumHalfwords:           Access size(unit: half-word)
 * @retval count for reading and writing dada error
 */
static uint32_t MEMORY_Access16(uint32_t u3AccessAddr, uint32_t NumHalfwords)
{
    uint32_t i;
    uint32_t j;
    uint32_t u32TestErrCnt = 0UL;
    uint32_t u32MemoryAddr = u3AccessAddr;

    for (i = 0UL; i < NumHalfwords; i += DATA_BUF_LEN) {
        (void)MEMORY_Write16(u32MemoryAddr, m_au16WriteData, DATA_BUF_LEN);
        (void)MEMORY_Read16(u32MemoryAddr, m_au16ReadData, DATA_BUF_LEN);

        /* Verify data. */
        for (j = 0UL; j < DATA_BUF_LEN; j++) {
            if (m_au16WriteData[j] != m_au16ReadData[j]) {
                u32TestErrCnt++;
                DDL_Printf("Halfword read/write error: address = 0x%.8x; write data = 0x%x; read data = 0x%x\r\n",
                           (unsigned int)(u32MemoryAddr + j), (unsigned int)m_au16WriteData[j], (unsigned int)m_au16ReadData[j]);
            }
        }

        u32MemoryAddr += (DATA_BUF_LEN * sizeof(m_au16ReadData[0]));
        (void)memset(m_au16ReadData, 0, (DATA_BUF_LEN * sizeof(m_au16ReadData[0])));
        BSP_LED_Toggle(LED_BLUE);
    }

    return u32TestErrCnt;
}

/**
 * @brief  Access memory for word.
 * @param  [in] u3AccessAddr:           Memory address
 * @param  [in] NumWords:               Access size(unit: word)
 * @retval count for reading and writing dada error
 */
static uint32_t MEMORY_Access32(uint32_t u3AccessAddr, uint32_t NumWords)
{
    uint32_t i;
    uint32_t j;
    uint32_t u32TestErrCnt = 0UL;
    uint32_t u32MemoryAddr = u3AccessAddr;

    for (i = 0UL; i < NumWords; i += DATA_BUF_LEN) {
        (void)MEMORY_Write32(u32MemoryAddr, m_au32WriteData, DATA_BUF_LEN);
        (void)MEMORY_Read32(u32MemoryAddr, m_au32ReadData, DATA_BUF_LEN);

        /* Verify data. */
        for (j = 0UL; j < DATA_BUF_LEN; j++) {
            if (m_au32WriteData[j] != m_au32ReadData[j]) {
                u32TestErrCnt++;
                DDL_Printf("Word read/write error: address = 0x%.8x; write data = 0x%.8x; read data = 0x%.8x\r\n",
                           (unsigned int)(u32MemoryAddr + j), (unsigned int)m_au32WriteData[j], (unsigned int)m_au32ReadData[j]);
            }
        }

        u32MemoryAddr += (DATA_BUF_LEN * sizeof(m_au32ReadData[0]));
        (void)memset(m_au32ReadData, 0, (DATA_BUF_LEN * sizeof(m_au32ReadData[0])));
        BSP_LED_Toggle(LED_BLUE);
    }

    return u32TestErrCnt;
}


void sdram_test(void)
{
	uint32_t ts=0;
	printf("write testsdram:\r\n");
	for(ts=1;ts<100;ts++)
	{
		testsdram[ts]=ts;
		printf("%02x ",testsdram[ts]); 
		if((ts%10)==0)
		{
			printf("\r\n"); 
		}
	}
	printf("\r\n");
	
	DDL_DelayMS(500UL);
	printf("read testsdram:\r\n");
	for(ts=1;ts<100;ts++)
	{
		printf("%02x ",testsdram[ts]);
		if((ts%10)==0)
		{
			printf("\r\n");
		}
	}
	printf("\r\n");
}

2.2、main.c

#include "main.h"
#include "lcd.h"
#include "sram.h"
#include "timer0.h"
#include "led.h"
#include "touch.h"
#include "can.h"
#include "adc.h"
#include "sdram.h"


stc_touchpad_data_t touchdat;
void SysTick_Handler(void)
{
    SysTick_IncTick();
		led1_tog();
}

int32_t main(void)
{
	
	uint16_t u=0;
	uint8_t i=0;
	uint16_t cord[6]={WHITE, BLUE, BRED, GBLUE, RED, YELLOW};
	/* Register write enable for some required peripherals. */
	LL_PERIPH_WE(LL_PERIPH_GPIO | LL_PERIPH_FCG | LL_PERIPH_PWC_CLK_RMU | LL_PERIPH_EFM | LL_PERIPH_SRAM);

	BSP_CLK_Init();
	/* EXCLK 60MHz */
	CLK_SetClockDiv(CLK_BUS_EXCLK, CLK_EXCLK_DIV4);
	DDL_PrintfInit(BSP_PRINTF_DEVICE, BSP_PRINTF_BAUDRATE, BSP_PRINTF_Preinit);
	BSP_IO_Init();
	BSP_LED_Init();
	//BSP_LCD_IO_Init();
	
	//init_led();
	//init_touch();
	//init_lcd();
	//init_sram();
	//init_timer0();
	//init_can();
	//init_adc();
	init_sdram();
	//SysTick_Init(1000U);

	LL_PERIPH_WP(LL_PERIPH_GPIO | LL_PERIPH_FCG | LL_PERIPH_PWC_CLK_RMU | LL_PERIPH_EFM | LL_PERIPH_SRAM);
	POINT_COLOR=RED;       
	LCD_Clear(WHITE);
	sdram_test();

	
	u=0;
	for (;;) 
	{

		BSP_LED_Toggle(LED_RED);
		DDL_DelayMS(500UL);
		BSP_LED_Toggle(LED_BLUE);
		DDL_DelayMS(500UL);
		
	}
}

3. Operation results

Serial port output information:

Write data into SDRAM and read data from SDRAM.

This post is from Domestic Chip Exchange

Latest reply

Can you please introduce the programming process of the read and write test of the SDRAM memory on the board?   Details Published on 2023-3-27 07:29
 
 

6555

Posts

0

Resources
2
 

Can you please introduce the programming process of the read and write test of the SDRAM memory on the board?

This post is from Domestic Chip Exchange
 
 
 

Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list