Skip to content

Commit 0eb0e2b

Browse files
danieldegrassecarlescufi
authored andcommitted
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 <[email protected]>
1 parent abfdbd6 commit 0eb0e2b

File tree

6 files changed

+168
-0
lines changed

6 files changed

+168
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
5+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
6+
project(memc)
7+
8+
target_sources(app PRIVATE src/main.c)

samples/drivers/memc/README.rst

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
.. _memc:
2+
3+
MEMC Driver Sample
4+
##################
5+
6+
Overview
7+
********
8+
9+
This sample can be used with any memory controller driver that
10+
memory maps external RAM. It is intended to demonstrate
11+
the ability to read and write from the memory mapped region.
12+
13+
Note that the chosen region (set by ``sram-ext`` dt alias node) should not
14+
overlap with memory used for XIP or SRAM by the application, as the sample
15+
would overwrite this data
16+
17+
18+
Building and Running
19+
********************
20+
21+
This application can be built and executed on an RT595 EVK as follows:
22+
23+
.. zephyr-app-commands::
24+
:zephyr-app: samples/drivers/memc
25+
:host-os: unix
26+
:board: mimxrt595_evk_cm33
27+
:goals: run
28+
:compact:
29+
30+
To build for another board, change "mimxrt595_evk_cm33" above to that
31+
board's name.
32+
33+
Sample Output
34+
=============
35+
36+
.. code-block:: console
37+
38+
*** Booting Zephyr OS build zephyr-v3.2.0-2686-gd52d828c2bdc ***
39+
Writing to memory region with base 0x38000000, size 0x800000
40+
41+
First 1KB of Data in memory:
42+
\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=
43+
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
44+
10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
45+
20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
46+
....
47+
48+
Read data matches written data
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/*
2+
* Copyright 2022 NXP
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/ {
8+
aliases {
9+
sram-ext = &aps6408l;
10+
};
11+
};

samples/drivers/memc/prj.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CONFIG_MEMC=y

samples/drivers/memc/sample.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
sample:
2+
description: Memory controller sample
3+
name: memc driver sample
4+
common:
5+
tags: memc
6+
filter: dt_alias_exists("sram-ext")
7+
integration_platforms:
8+
- mimxrt595_evk_cm33
9+
harness: console
10+
harness_config:
11+
type: one_line
12+
regex:
13+
- "Read data matches written data"
14+
tests:
15+
sample.drivers.memc:
16+
tags: memc

samples/drivers/memc/src/main.c

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* Copyright 2022 NXP
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/kernel.h>
8+
9+
#if DT_HAS_COMPAT_STATUS_OKAY(nxp_imx_flexspi)
10+
/* FlexSPI memory mapped region is second register property of parent dev */
11+
#define MEMC_BASE DT_REG_ADDR_BY_IDX(DT_PARENT(DT_ALIAS(sram_ext)), 1)
12+
#define MEMC_SIZE (DT_PROP(DT_ALIAS(sram_ext), size) / 8)
13+
#endif
14+
15+
void dump_memory(uint8_t *p, uint32_t size)
16+
{
17+
uint32_t i, j;
18+
19+
for (i = 0, j = 0; j < (size / 16); i += 16, j++) {
20+
printk("%02x %02x %02x %02x %02x %02x %02x %02x ",
21+
p[i], p[i+1], p[i+2], p[i+3],
22+
p[i+4], p[i+5], p[i+6], p[i+7]);
23+
printk("%02x %02x %02x %02x %02x %02x %02x %02x\n",
24+
p[i+8], p[i+9], p[i+10], p[i+11],
25+
p[i+12], p[i+13], p[i+14], p[i+15]);
26+
/* Split dump at 256B boundaries */
27+
if (((i + 16) & 0xFF) == 0) {
28+
printk("\n");
29+
}
30+
}
31+
/* Dump any remaining data after 16 byte blocks */
32+
for (; i < size; i++) {
33+
printk("%02x ", p[i]);
34+
}
35+
printk("\n");
36+
}
37+
38+
#define BUF_SIZE 1024
39+
40+
uint8_t memc_write_buffer[BUF_SIZE];
41+
uint8_t memc_read_buffer[BUF_SIZE];
42+
43+
void main(void)
44+
{
45+
uint8_t *memc = (uint8_t *)MEMC_BASE;
46+
uint32_t i, j;
47+
48+
/* Initialize write buffer */
49+
for (uint32_t i = 0; i < BUF_SIZE; i++) {
50+
memc_write_buffer[i] = (uint8_t)i;
51+
}
52+
printk("Writing to memory region with base 0x%0x, size 0x%0x\n\n",
53+
MEMC_BASE, MEMC_SIZE);
54+
/* Copy write buffer into memc region */
55+
for (i = 0, j = 0; j < (MEMC_SIZE / BUF_SIZE); i += BUF_SIZE, j++) {
56+
memcpy(memc + i, memc_write_buffer, BUF_SIZE);
57+
}
58+
/* Copy any remaining space bytewise */
59+
for (; i < MEMC_SIZE; i++) {
60+
memc[i] = memc_write_buffer[i];
61+
}
62+
/* Read from memc region into buffer */
63+
for (i = 0, j = 0; j < (MEMC_SIZE / BUF_SIZE); i += BUF_SIZE, j++) {
64+
memcpy(memc_read_buffer, memc + i, BUF_SIZE);
65+
/* Compare memory */
66+
if (memcmp(memc_read_buffer, memc_write_buffer, BUF_SIZE)) {
67+
printk("Error: read data differs in range [0x%x- 0x%x]\n",
68+
i, i + (BUF_SIZE - 1));
69+
return;
70+
}
71+
}
72+
/* Copy any remaining space bytewise */
73+
for (; i < MEMC_SIZE; i++) {
74+
memc_read_buffer[i] = memc[i];
75+
if (memc_write_buffer[i] != memc_read_buffer[i]) {
76+
printk("Error: read data differs at offset 0x%x\n", i);
77+
return;
78+
}
79+
}
80+
printk("First 1KB of Data in memory:\n");
81+
printk("===========================\n");
82+
dump_memory(memc, MIN(MEMC_SIZE, KB(1)));
83+
printk("Read data matches written data\n");
84+
}

0 commit comments

Comments
 (0)