From acfffb13a9e1a06e0e554ec888dd53ab20ecca9d Mon Sep 17 00:00:00 2001 From: Silvano Seva Date: Fri, 1 Aug 2025 20:42:56 +0200 Subject: [PATCH] tests: platform: added nonvolatile memory dump tool --- tests/platform/nvm_dump.c | 145 ++++++++++++++++++++++++++++ tests/platform/nvm_test.c | 193 -------------------------------------- 2 files changed, 145 insertions(+), 193 deletions(-) create mode 100644 tests/platform/nvm_dump.c delete mode 100644 tests/platform/nvm_test.c diff --git a/tests/platform/nvm_dump.c b/tests/platform/nvm_dump.c new file mode 100644 index 00000000..818641bb --- /dev/null +++ b/tests/platform/nvm_dump.c @@ -0,0 +1,145 @@ +/*************************************************************************** + * Copyright (C) 2025 by Federico Amedeo Izzo IU2NUO, * + * Niccolò Izzo IU2KIN * + * Frederik Saraci IU2NRO * + * Silvano Seva IU2KWO * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, see * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define LINE_LENGTH 16 +#define CHUNK_SIZE (LINE_LENGTH * 2) + +static void printChunk(size_t offset, void *chunk, size_t len) +{ + uint8_t *ptr = ((uint8_t *) chunk); + + for(size_t j = 0; j < len / LINE_LENGTH; j++) { + printf("%08x: ", offset + (j * LINE_LENGTH)); + + for(size_t i = 0; i < LINE_LENGTH; i++) + printf("%02x ", ptr[(j * LINE_LENGTH) + i]); + + for(size_t i = 0; i < LINE_LENGTH; i++) { + char elem = (char) ptr[(j * LINE_LENGTH) + i]; + + if((elem > 0x20) && (elem < 0x7f)) + putchar(elem); + else + putchar('.'); + } + + puts("\r"); + } +} + +static void waitForPtt() +{ + // Wait until PTT is pressed + while(platform_getPttStatus() == false) { + platform_ledOn(GREEN); + sleepFor(0, 500); + platform_ledOff(GREEN); + sleepFor(0, 500); + } + + // Resume execution on PTT release + platform_ledOn(RED); + while(platform_getPttStatus() == true) ; + platform_ledOff(RED); +} + +static bool pttLongPress() +{ + static uint32_t timeout; + bool ptt = platform_getPttStatus(); + + if(ptt == false) + timeout = 250; + else + timeout -= 1; + + return (timeout == 0); +} + +int main() +{ + platform_init(); + nvm_init(); + + // Wait for user to be ready + waitForPtt(); + + size_t idx = 0; + const struct nvmDescriptor *nvm = nvm_getDesc(0); + + if(nvm == NULL) { + puts("No NVM areas available, end!\r\n"); + + while(1) { + platform_ledOn(RED); + sleepFor(0, 500); + platform_ledOff(RED); + sleepFor(0, 500); + } + } + + while(nvm != NULL) { + printf("NVM device %d:\r\n", idx); + printf("\t - Name: %s\r\n", nvm->name); + printf("\t - Size: %d\r\n", nvm->dev->size); + printf("\t - Flags: %04lx\r\n", nvm->dev->info->device_info); + puts("\r"); + + idx += 1; + nvm = nvm_getDesc(idx); + } + + for(size_t i = 0; i < idx; i++) { + nvm = nvm_getDesc(i); + + printf("\r\nNVM device %d: press PTT to dump\r\n", i); + waitForPtt(); + + for(size_t addr = 0; addr < nvm->dev->size; addr += CHUNK_SIZE) { + uint8_t chunk[CHUNK_SIZE]; + + nvm_devRead(nvm->dev, addr, chunk, sizeof(chunk)); + printChunk(addr, chunk, sizeof(chunk)); + + // Exit in case of PTT press + if(pttLongPress() == true) + break; + } + } + + // Loop endlessly + while(1) { + platform_ledOn(RED); + sleepFor(0, 500); + platform_ledOff(RED); + sleepFor(0, 500); + } + + return 0; +} diff --git a/tests/platform/nvm_test.c b/tests/platform/nvm_test.c deleted file mode 100644 index 9524e25e..00000000 --- a/tests/platform/nvm_test.c +++ /dev/null @@ -1,193 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2020 - 2025 by Federico Amedeo Izzo IU2NUO, * - * Niccolò Izzo IU2KIN * - * Frederik Saraci IU2NRO * - * Silvano Seva IU2KWO * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, see * - ***************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include - - -#define FLASH_TEST_ADDR 0x10000 -#define EEPROM_TEST_ADDR 0x00000 - - -static void printChunk(void *chunk, size_t len) -{ - printf("\n\r"); - - uint8_t *ptr = ((uint8_t *) chunk); - for(size_t j = 0; j < len / 16; j++) - { - for(size_t i = 0; i < 16; i++) - printf("%02x ", ptr[j * 16 + i]); - - for(size_t i = 0; i < 16; i++) - { - if((ptr[i] > 0x22) && (ptr[i] < 0x7f)) printf("%c", ptr[j * 16 + i]); - else printf("."); - } - - printf("\n\r"); - } -} - -static int flashTest(const struct nvmArea *nvm, const size_t address) -{ - const struct nvmParams *params = nvmArea_params(nvm); - - char *buffer1 = (char *) malloc(params->erase_size); - char *buffer2 = (char *) malloc(params->erase_size); - - // Read one block - int ret = nvmArea_read(nvm, address, buffer1, params->erase_size); - printf("Flash area read returned value %d\r\n", ret); - if(ret < 0) - return ret; - - printChunk(buffer1, params->erase_size); - - // Erase one block - ret = nvmArea_erase(nvm, address, params->erase_size); - printf("Flash erase returned value %d\r\n", ret); - if(ret < 0) - return ret; - - // Read back to confirm Erase - ret = nvmArea_read(nvm, address, buffer2, params->erase_size); - if(ret < 0) - return ret; - - for(size_t i = 0; i < params->erase_size; i++) - { - if (buffer2[i] != 0xff) - { - printf("Flash test fail! Offset %d was not erased!\r\n", i); - printChunk(buffer2, params->erase_size); - return -1; - } - } - - // Write one block - ret = nvmArea_write(nvm, address, buffer1, params->erase_size); - printf("Flash area write returned value %d\r\n", ret); - if(ret < 0) - return ret; - - // Read back to confirm Write - ret = nvmArea_read(nvm, address, buffer2, params->erase_size); - printf("Flash area readback returned value %d\r\n", ret); - if(ret < 0) - return ret; - - if(memcmp(buffer1, buffer2, params->erase_size)) - { - puts("Error in flash device write, content to write and written differ!\r\n"); - printChunk(buffer2, params->erase_size); - return -1; - } - - puts("Flash test passed\r\n"); - return 0; -} - -static int eepromTest(const struct nvmArea *nvm, const size_t address) -{ - uint8_t chunk[128]; - - int ret = nvmArea_read(nvm, address, chunk, sizeof(chunk)); - printf("EEPROM read operation returned %d\r\n", ret); - if(ret < 0) - return ret; - - printChunk(chunk, sizeof(chunk)); - - for(size_t i = 0; i < sizeof(chunk); i += 2) - { - chunk[i] = 0x55; - chunk[i + 1] = 0xAA; - } - - ret = nvmArea_write(nvm, address, chunk, sizeof(chunk)); - printf("EEPROM write operation returned %d\r\n", ret); - if(ret < 0) - return ret; - - memset(chunk, 0x00, sizeof(chunk)); - ret = nvmArea_read(nvm, address, chunk, sizeof(chunk)); - printf("EEPROM readback operation returned %d\r\n", ret); - if(ret < 0) - return ret; - - for(size_t i = 0; i < sizeof(chunk); i += 2) - { - if((chunk[i] != 0x55) || (chunk[i + 1] != 0xAA)) - { - printf("Check error around index %d: memory[i] = %02x, memory[i + 1] = %02x\r\n", - i, chunk[i], chunk[i + 1]); - return -1; - } - } - - puts("EEPROM test passed\r\n"); - return 0; -} - -int main() -{ - platform_init(); - delayMs(2000); - - // This is generally called in platform_init() - nvm_init(); - - const struct nvmArea *nvm; - size_t num = nvm_getMemoryAreas(&nvm); - - if(num == 0) - { - puts("Error: no NVM areas available\r\n"); - while(1) ; - } - - for(size_t i = 0; i < num; i++) - { - const struct nvmParams *params = nvmArea_params(&nvm[i]); - if(params->type == NVM_FLASH) - { - printf("Found flash area at index %d, performing test...\r\n", i); - flashTest(&nvm[i], FLASH_TEST_ADDR); - } - - if(params->type == NVM_EEPROM) - { - printf("Found EEPROM area at index %d, performing test...\r\n", i); - eepromTest(&nvm[i], EEPROM_TEST_ADDR); - } - } - - // Loop endlessly - while(1) ; - - return 0; -}