【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.
|