samples: drivers: memc: add sample to test memory controllers

Add sample to test memory controllers that map external RAM into
SOC address space. This sample uses the "sram-ext" alias
node to determine the base address and size of the external RAM
device.

Signed-off-by: Daniel DeGrasse <daniel.degrasse@nxp.com>
This commit is contained in:
Daniel DeGrasse 2022-12-20 17:10:49 -06:00 committed by Carles Cufí
commit 0eb0e2b025
6 changed files with 168 additions and 0 deletions

View file

@ -0,0 +1,8 @@
# SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(memc)
target_sources(app PRIVATE src/main.c)

View file

@ -0,0 +1,48 @@
.. _memc:
MEMC Driver Sample
##################
Overview
********
This sample can be used with any memory controller driver that
memory maps external RAM. It is intended to demonstrate
the ability to read and write from the memory mapped region.
Note that the chosen region (set by ``sram-ext`` dt alias node) should not
overlap with memory used for XIP or SRAM by the application, as the sample
would overwrite this data
Building and Running
********************
This application can be built and executed on an RT595 EVK as follows:
.. zephyr-app-commands::
:zephyr-app: samples/drivers/memc
:host-os: unix
:board: mimxrt595_evk_cm33
:goals: run
:compact:
To build for another board, change "mimxrt595_evk_cm33" above to that
board's name.
Sample Output
=============
.. code-block:: console
*** Booting Zephyr OS build zephyr-v3.2.0-2686-gd52d828c2bdc ***
Writing to memory region with base 0x38000000, size 0x800000
First 1KB of Data in memory:
\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
....
Read data matches written data

View file

@ -0,0 +1,11 @@
/*
* Copyright 2022 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
/ {
aliases {
sram-ext = &aps6408l;
};
};

View file

@ -0,0 +1 @@
CONFIG_MEMC=y

View file

@ -0,0 +1,16 @@
sample:
description: Memory controller sample
name: memc driver sample
common:
tags: memc
filter: dt_alias_exists("sram-ext")
integration_platforms:
- mimxrt595_evk_cm33
harness: console
harness_config:
type: one_line
regex:
- "Read data matches written data"
tests:
sample.drivers.memc:
tags: memc

View file

@ -0,0 +1,84 @@
/*
* Copyright 2022 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#if DT_HAS_COMPAT_STATUS_OKAY(nxp_imx_flexspi)
/* FlexSPI memory mapped region is second register property of parent dev */
#define MEMC_BASE DT_REG_ADDR_BY_IDX(DT_PARENT(DT_ALIAS(sram_ext)), 1)
#define MEMC_SIZE (DT_PROP(DT_ALIAS(sram_ext), size) / 8)
#endif
void dump_memory(uint8_t *p, uint32_t size)
{
uint32_t i, j;
for (i = 0, j = 0; j < (size / 16); i += 16, j++) {
printk("%02x %02x %02x %02x %02x %02x %02x %02x ",
p[i], p[i+1], p[i+2], p[i+3],
p[i+4], p[i+5], p[i+6], p[i+7]);
printk("%02x %02x %02x %02x %02x %02x %02x %02x\n",
p[i+8], p[i+9], p[i+10], p[i+11],
p[i+12], p[i+13], p[i+14], p[i+15]);
/* Split dump at 256B boundaries */
if (((i + 16) & 0xFF) == 0) {
printk("\n");
}
}
/* Dump any remaining data after 16 byte blocks */
for (; i < size; i++) {
printk("%02x ", p[i]);
}
printk("\n");
}
#define BUF_SIZE 1024
uint8_t memc_write_buffer[BUF_SIZE];
uint8_t memc_read_buffer[BUF_SIZE];
void main(void)
{
uint8_t *memc = (uint8_t *)MEMC_BASE;
uint32_t i, j;
/* Initialize write buffer */
for (uint32_t i = 0; i < BUF_SIZE; i++) {
memc_write_buffer[i] = (uint8_t)i;
}
printk("Writing to memory region with base 0x%0x, size 0x%0x\n\n",
MEMC_BASE, MEMC_SIZE);
/* Copy write buffer into memc region */
for (i = 0, j = 0; j < (MEMC_SIZE / BUF_SIZE); i += BUF_SIZE, j++) {
memcpy(memc + i, memc_write_buffer, BUF_SIZE);
}
/* Copy any remaining space bytewise */
for (; i < MEMC_SIZE; i++) {
memc[i] = memc_write_buffer[i];
}
/* Read from memc region into buffer */
for (i = 0, j = 0; j < (MEMC_SIZE / BUF_SIZE); i += BUF_SIZE, j++) {
memcpy(memc_read_buffer, memc + i, BUF_SIZE);
/* Compare memory */
if (memcmp(memc_read_buffer, memc_write_buffer, BUF_SIZE)) {
printk("Error: read data differs in range [0x%x- 0x%x]\n",
i, i + (BUF_SIZE - 1));
return;
}
}
/* Copy any remaining space bytewise */
for (; i < MEMC_SIZE; i++) {
memc_read_buffer[i] = memc[i];
if (memc_write_buffer[i] != memc_read_buffer[i]) {
printk("Error: read data differs at offset 0x%x\n", i);
return;
}
}
printk("First 1KB of Data in memory:\n");
printk("===========================\n");
dump_memory(memc, MIN(MEMC_SIZE, KB(1)));
printk("Read data matches written data\n");
}