1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/tests/cpu/avr8_xmega_drivers/test_ebi.c

280 lines
6.9 KiB
C

/*
* Copyright (C) 2021 Gerson Fernando Budke <nandojve@gmail.com>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup tests
* @{
*
* @file
* @brief External Bus Interface test application for ATxmega A1x
*
* @author Gerson Fernando Budke <nandojve@gmail.com>
*
* @}
*/
#if defined(MODULE_ATXMEGA_EBI)
#include "board.h"
#include "cpu_ebi.h"
#include "errno.h"
#include "cpu_tests.h"
#if defined(BOARD_ATXMEGA_A1U_XPRO)
/**
* 512k bytes installed
* 256k bytes are truly addressable because of board layout
* 64k bytes reserved for RIOT-OS
* 192k bytes are addressable by hugemem methods.
* Free for user
* This is tested here
*/
#define BOARD_EBI_RAM_BASE (0x10000)
#define BOARD_EBI_RAM_SIZE (0x30000)
#elif defined(BOARD_ATXMEGA_A1_XPLAINED)
/**
* 8MB bytes installed
* 64k bytes reserved for RIOT-OS
*
* The remaining memory can be addressable by hugemem methods.
* It is free for user and it is tested here
*/
#define BOARD_EBI_RAM_BASE (0x10000)
#define BOARD_EBI_RAM_SIZE (0x7F0000)
#else
/**
* 128k bytes installed
* 64k bytes reserved for RIOT-OS
* 64k bytes free for user and it is tested here
*/
#define BOARD_EBI_RAM_BASE (0x10000)
#define BOARD_EBI_RAM_SIZE (0x10000)
#endif
/**
* @brief Test the EBI data bus wired to the SRAM
*
* This function will perform a walking 1s to locate any shorts or open leads
* to the SRAM device.
*
* @param base Test Area base address of the external memory device
*
* @retval 0 on success, and @ref errno on failure
*/
static int8_t ebi_test_data_bus(hugemem_ptr_t base)
{
hugemem_ptr_t p;
uint8_t i;
/* Write walking 1s */
for (p = base, i = 0; i < 32; i++) {
hugemem_write32(p, 1UL << i);
p = (hugemem_ptr_t)((uint32_t)p + sizeof(uint32_t));
}
/* Read walking 1s, write walking 0s */
for (p = base, i = 0; i < 32; i++) {
uint32_t expected = 1UL << i;
uint32_t actual;
actual = hugemem_read32(p);
if (actual != expected) {
return -EIO;
}
hugemem_write32(p, ~expected);
p = (hugemem_ptr_t)((uint32_t)p + sizeof(uint32_t));
}
/* Read walking 0s */
for (p = base, i = 0; i < 32; i++) {
uint32_t actual;
uint32_t expected = ~(1UL << i);
actual = hugemem_read32(p);
if (actual != expected) {
return -EIO;
}
p = (hugemem_ptr_t)((uint32_t)p + sizeof(uint32_t));
}
return 0;
}
/**
* @brief Test the EBI address bus wired to the SRAM
*
* This function will perform an address bus test to locate any shorts or open
* leads to the SRAM device.
*
* @param base Test Area base address of the external memory device
* @param size Size of the external memory device
*
* @retval 0 on success, and @ref errno on failure
*/
static int8_t ebi_test_addr_bus(hugemem_ptr_t base, uint32_t size)
{
uint32_t offset;
uint8_t i;
/* Initialize all power-of-two locations with 0x55 */
hugemem_write8(base, 0x55);
for (offset = 1; offset < size; offset <<= 1) {
hugemem_ptr_t p;
p = (hugemem_ptr_t)((uint32_t)base + offset);
hugemem_write8(p, 0x55);
}
/* Check for address lines stuck high */
hugemem_write8(base, 0xaa);
for (i = 0, offset = 1; offset < size; offset <<= 1, i++) {
hugemem_ptr_t p;
uint8_t actual;
p = (hugemem_ptr_t)((uint32_t)base + offset);
actual = hugemem_read8(p);
if (actual != 0x55) {
return -EIO;
}
}
/* Check for address lines stuck low or shorted */
hugemem_write8(base, 0x55);
for (i = 0, offset = 1; offset < size; offset <<= 1, i++) {
hugemem_ptr_t p;
uint32_t offset2;
uint8_t j;
uint8_t actual;
p = (hugemem_ptr_t)((uint32_t)base + offset);
hugemem_write8(p, 0xaa);
actual = hugemem_read8(base);
if (actual != 0x55) {
return -EIO;
}
for (j = 0, offset2 = 1; offset2 < size; offset2 <<= 1, j++) {
hugemem_ptr_t q;
if (offset2 == offset) {
continue;
}
q = (hugemem_ptr_t)((uint32_t)base + offset2);
actual = hugemem_read8(q);
if (actual != 0x55) {
return -EIO;
}
}
hugemem_write8(p, 0x55);
}
return 0;
}
/**
* @brief Perform a SRAM data integrity test
*
* This function will perform a SRAM data integrity test by writing 0s and 1s
* to the entire external device.
*
* @param base Test Area base address of the external memory device
* @param size Size of the external memory device
*
* @retval 0 on success, and @ref errno on failure
*/
static int8_t ebi_test_data_integrity(hugemem_ptr_t base, uint32_t size)
{
uint32_t offset;
uint32_t pattern;
/* Fill memory with a known pattern. */
for (pattern = 1, offset = 0; offset < size; pattern++,
offset += sizeof(uint32_t)) {
hugemem_ptr_t p;
p = (hugemem_ptr_t)((uint32_t)base + offset);
hugemem_write32(p, pattern);
}
/* Check each location and invert it for the second pass. */
for (pattern = 1, offset = 0; offset < size; pattern++,
offset += sizeof(uint32_t)) {
hugemem_ptr_t p;
uint32_t actual;
uint32_t expected;
p = (hugemem_ptr_t)((uint32_t)base + offset);
actual = hugemem_read32(p);
if (actual != pattern) {
return -EIO;
}
expected = ~pattern;
hugemem_write32(p, expected);
}
/* Check each location for the inverted pattern and zero it. */
for (pattern = 1, offset = 0; offset < size; pattern++,
offset += sizeof(uint32_t)) {
hugemem_ptr_t p;
uint32_t actual;
uint32_t expected;
p = (hugemem_ptr_t)((uint32_t)base + offset);
expected = ~pattern;
actual = hugemem_read32(p);
if (actual != expected) {
return -EIO;
}
}
return 0;
}
void ebi_tests(void)
{
uint8_t ret;
puts("bus connectivity");
ret = ebi_test_data_bus((hugemem_ptr_t)BOARD_EBI_RAM_BASE);
if (ret) {
goto out;
}
puts("addrresing");
ret = ebi_test_addr_bus((hugemem_ptr_t)BOARD_EBI_RAM_BASE,
BOARD_EBI_RAM_SIZE);
if (ret) {
goto out;
}
puts("data integrity");
ret = ebi_test_data_integrity((hugemem_ptr_t)BOARD_EBI_RAM_BASE,
BOARD_EBI_RAM_SIZE);
if (ret) {
goto out;
}
out:
if (ret) {
puts("TEST FAILED");
}
else {
puts("TEST SUCCEEDED");
}
}
#endif /* MODULE_ATXMEGA_EBI */