From 8b2298db2604e31ee0d5e7853935060cc0c3d6dd Mon Sep 17 00:00:00 2001 From: Jakob Krantz Date: Mon, 25 Sep 2023 10:20:44 +0200 Subject: [PATCH] WIP: RTT transfer of filesystem --- app/CMakeLists.txt | 1 + .../zswatch_nrf5340_cpuapp_3.conf | 15 +- app/prj.conf | 4 +- app/scripts/rtt.py | 196 ++++++++ app/src/main.c | 72 ++- app/src/zsw_flash.c | 446 ++++++------------ app/src/zsw_flash.h | 3 + app/src/zsw_rtt_transfer.c | 51 ++ app/src/zsw_rtt_transfer.h | 6 + app/zephyr/module.yml | 20 - 10 files changed, 478 insertions(+), 336 deletions(-) create mode 100644 app/scripts/rtt.py create mode 100644 app/src/zsw_rtt_transfer.c create mode 100644 app/src/zsw_rtt_transfer.h delete mode 100644 app/zephyr/module.yml diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 0b23caf3..e745c8b4 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -52,6 +52,7 @@ target_sources(app PRIVATE src/zsw_pressure_sensor.c) target_sources(app PRIVATE src/zsw_light_sensor.c) target_sources(app PRIVATE src/zsw_flash.c) +target_sources(app PRIVATE src/zsw_rtt_transfer.c) if (DFU_BUILD) target_sources(app PRIVATE src/dfu.c) diff --git a/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_3.conf b/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_3.conf index cb0a4efa..a1d7d314 100644 --- a/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_3.conf +++ b/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_3.conf @@ -12,18 +12,9 @@ CONFIG_SPI_NOR_IDLE_IN_DPD=y CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 CONFIG_MPU_ALLOW_FLASH_WRITE=y -CONFIG_FILE_SYSTEM=y -CONFIG_FILE_SYSTEM_LITTLEFS=y +#CONFIG_FILE_SYSTEM=y +#CONFIG_FILE_SYSTEM_LITTLEFS=y CONFIG_LOG=n -CONFIG_LV_Z_USE_FILESYSTEM=y -CONFIG_MCUMGR_GRP_FS=y -CONFIG_MCUMGR=y -CONFIG_FILE_SYSTEM_SHELL=y -CONFIG_SHELL_BACKEND_SERIAL=n -CONFIG_SHELL_BACKEND_RTT=y -CONFIG_SHELL=y +#CONFIG_LV_Z_USE_FILESYSTEM=y CONFIG_USE_SEGGER_RTT=y -CONFIG_SHELL_BACKEND_RTT_BUFFER=0 -CONFIG_LOG_BACKEND_RTT_BUFFER=1 -CONFIG_ZCBOR=y diff --git a/app/prj.conf b/app/prj.conf index da8134f7..aad1548a 100644 --- a/app/prj.conf +++ b/app/prj.conf @@ -1,5 +1,5 @@ CONFIG_LV_Z_MEM_POOL_NUMBER_BLOCKS=8 -CONFIG_MAIN_STACK_SIZE=1024 +CONFIG_MAIN_STACK_SIZE=2048 CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 CONFIG_HEAP_MEM_POOL_SIZE=25000 CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y @@ -184,7 +184,7 @@ CONFIG_DEMO_BUILD=n # Choose one or many of below CONFIG_WATCHFACE_ANALOG=n -CONFIG_WATCHFACE_DIGITAL=n +CONFIG_WATCHFACE_DIGITAL=y CONFIG_WATCHFACE_MINIMAL=y # Choose one of below diff --git a/app/scripts/rtt.py b/app/scripts/rtt.py new file mode 100644 index 00000000..19822cde --- /dev/null +++ b/app/scripts/rtt.py @@ -0,0 +1,196 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright 2017 Square, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# Example RTT terminal. +# +# This module creates an interactive terminal with the target using RTT. +# +# Usage: rtt target_device +# Author: Charles Nicholson +# Date: October 11, 2017 +# Copyright: 2017 Square, Inc. + +import pylink +import argparse +import sys +import time +import os +from six.moves import input + +try: + import thread +except ImportError: + import _thread as thread + + +def read_rtt(jlink): + """Reads the JLink RTT buffer #0 at 10Hz and prints to stdout. + + This method is a polling loop against the connected JLink unit. If + the JLink is disconnected, it will exit. Additionally, if any exceptions + are raised, they will be caught and re-raised after interrupting the + main thread. + + sys.stdout.write and sys.stdout.flush are used since target terminals + are expected to transmit newlines, which may or may not line up with the + arbitrarily-chosen 1024-byte buffer that this loop uses to read. + + Args: + jlink (pylink.JLink): The JLink to read. + + Raises: + Exception on error. + """ + try: + while jlink.connected(): + terminal_bytes = jlink.rtt_read(0, 1024) + if terminal_bytes: + sys.stdout.write("".join(map(chr, terminal_bytes))) + sys.stdout.flush() + time.sleep(0.1) + except Exception: + print("IO read thread exception, exiting...") + thread.interrupt_main() + raise + + +def write_rtt(jlink): + """Writes kayboard input to JLink RTT buffer #0. + + This method is a loop that blocks waiting on stdin. When enter is pressed, + LF and NUL bytes are added to the input and transmitted as a byte list. + If the JLink is disconnected, it will exit gracefully. If any other + exceptions are raised, they will be caught and re-raised after interrupting + the main thread. + + Args: + jlink (pylink.JLink): The JLink to write to. + + Raises: + Exception on error. + """ + try: + buffer_size = 4096 + counter = 0 + with open('lvgl_resources.bin', mode='rb') as f: + num_sent = 0 + file_size = os.fstat(f.fileno()).st_size + print('Filesize:', num_sent) + chunk = f.read(buffer_size) + while chunk and jlink.connected(): + time.sleep(1) + bytes_written = 0 + while bytes_written < len(chunk): + to_send = chunk[bytes_written:] + print("Sening", len(to_send)) + sent = jlink.rtt_write(2, chunk[bytes_written:]) + print('Wanted', len(chunk) - bytes_written, 'Sent', sent) + bytes_written = bytes_written + sent + time.sleep(1) + + num_sent = num_sent + len(chunk) + print(counter, num_sent, '/', file_size, 'len:', len(chunk)) + chunk = f.read(buffer_size) + counter = counter + 1 + #bytes = list(bytearray(input(), "utf-8") + b"\x0A\x00") + #print("Bytes:", bytes) + #break + print('File send done') + time.sleep(2) + bytes = list(b"\x0A\x00") + bytes_written = jlink.rtt_write(2, bytes) + print("Bytes:", bytes, 'Sent:', bytes_written) + + except Exception: + print("IO write thread exception, exiting...") + thread.interrupt_main() + raise + + +def main(target_device, block_address=None): + """Creates an interactive terminal to the target via RTT. + + The main loop opens a connection to the JLink, and then connects + to the target device. RTT is started, the number of buffers is presented, + and then two worker threads are spawned: one for read, and one for write. + + The main loops sleeps until the JLink is either disconnected or the + user hits ctrl-c. + + Args: + target_device (string): The target CPU to connect to. + block_address (int): optional address pointing to start of RTT block. + + Returns: + Always returns ``0`` or a JLinkException. + + Raises: + JLinkException on error. + """ + jlink = pylink.JLink() + print("connecting to JLink...") + jlink.open() + print("connecting to %s..." % target_device) + jlink.set_tif(pylink.enums.JLinkInterfaces.SWD) + jlink.connect(target_device) + print("connected, starting RTT...") + jlink.rtt_start(block_address) + + while True: + try: + num_up = jlink.rtt_get_num_up_buffers() + num_down = jlink.rtt_get_num_down_buffers() + print("RTT started, %d up bufs, %d down bufs." % (num_up, num_down)) + break + except pylink.errors.JLinkRTTException: + time.sleep(0.1) + + print("up channels:") + for buf_index in range(jlink.rtt_get_num_up_buffers()): + buf = jlink.rtt_get_buf_descriptor(buf_index, True) + print(" %d: name = %r, size = %d bytes, flags = %d" % (buf.BufferIndex, buf.name, + buf.SizeOfBuffer, buf.Flags)) + + print("down channels:") + for buf_index in range(jlink.rtt_get_num_down_buffers()): + buf = jlink.rtt_get_buf_descriptor(buf_index, False) + print(" %d: name = %r, size = %d bytes, flags = %d" % (buf.BufferIndex, buf.name, + buf.SizeOfBuffer, buf.Flags)) + + try: + thread.start_new_thread(read_rtt, (jlink,)) + thread.start_new_thread(write_rtt, (jlink,)) + while jlink.connected(): + time.sleep(1) + print("JLink disconnected, exiting...") + except KeyboardInterrupt: + print("ctrl-c detected, exiting...") + pass + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Open RTT console.") + parser.add_argument( + "target_cpu", + help="Device Name (see https://www.segger.com/supported-devices/jlink/)") + parser.add_argument( + "rtt_block_address", help="RTT block address in hex", + type=lambda x: int(x, 16), nargs="?") + + args = parser.parse_args() + + sys.exit(main(args.target_cpu, args.rtt_block_address)) \ No newline at end of file diff --git a/app/src/main.c b/app/src/main.c index d470133e..1d27f9f1 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -41,8 +41,9 @@ #include #include #include "dfu.h" +#include -LOG_MODULE_REGISTER(main, LOG_LEVEL_WRN); +LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG); #define TASK_WDT_FEED_INTERVAL_MS 3000 @@ -95,9 +96,8 @@ ZBUS_LISTENER_DEFINE(main_ble_comm_lis, zbus_ble_comm_data_callback); static void run_init_work(struct k_work *item) { lv_indev_t *touch_indev; - k_msleep(2000); - zsw_flash_test(); + //zsw_flash_test(); load_retention_ram(); notification_manager_init(); enable_bluetoth(); @@ -145,6 +145,8 @@ void run_wdt_work(struct k_work *item) k_work_schedule(&wdt_work, K_MSEC(TASK_WDT_FEED_INTERVAL_MS)); } +static uint8_t buf[4096]; +extern int asdf(void); int main(void) { #if defined(CONFIG_TASK_WDT) && !defined(CONFIG_BOARD_NATIVE_POSIX) @@ -165,6 +167,70 @@ int main(void) // this RAM forever, instead re-use the system workqueue for init // it has the required amount of stack. k_work_submit(&init_work); + int counter = 0; + int buffer_index = 0; + int bytes_flashed = 0; + + while (1) { + int len_to_read = sizeof(buf) - buffer_index; + int len = zsw_rtt_transfer_read(&buf[buffer_index], len_to_read); + if (len != 0) { + LOG_DBG("Want: %d, Got: %d", len_to_read, len); + } + + if (len == 0) { + + } else if (len == 2) { + LOG_WRN("RTT Transfer done: %d bytes flashed", bytes_flashed); + break; + } else if (len == len_to_read) { + asdf(); + bytes_flashed += sizeof(buf); + LOG_DBG("Write: %d, %d", buffer_index, bytes_flashed); + //asdf(); + //k_msleep(100); + //int ret = zsw_flash_write_sector(counter, buf, sizeof(buf)); + //if (ret != 0) { + // TODO? + //} + //LOG_DBG("zsw_flash_write_sector: %d", ret); + + counter++; + buffer_index = 0; + if (counter % 10 == 0) { + LOG_WRN("RTT: Received %d (%d)", bytes_flashed, counter); + } + } else { + buffer_index += len; + if (buffer_index > sizeof(buf)) { + __ASSERT(false, "Something wrong got size %d", buffer_index); + } + LOG_DBG("Fill: %d", buffer_index); + } + k_msleep(100); + /* + if (len > 0) { + if (len == 2) { + LOG_WRN("RTT Transfer done: %d bytes received", total_bytes); + break; + } + total_bytes += len; + counter++; + + int ret = zsw_flash_write_sector(counter, buf, len); + if (ret != 0) { + // ? + } + if (counter % 10 == 0) { + LOG_WRN("RTT: Received %d (%d)", total_bytes, counter); + } + k_msleep(50); + } else { + k_msleep(50); + //zsw_rtt_transfer_write(buf, len - 1); + } + */ + } return 0; } diff --git a/app/src/zsw_flash.c b/app/src/zsw_flash.c index 9d411790..4806f6d7 100644 --- a/app/src/zsw_flash.c +++ b/app/src/zsw_flash.c @@ -4,344 +4,192 @@ * SPDX-License-Identifier: Apache-2.0 */ - -#include - #include +#include #include -#include -#include -#include -#include -#include - -LOG_MODULE_REGISTER(zsw_flash, LOG_LEVEL_DBG); - -/* Matches LFS_NAME_MAX */ -#define MAX_PATH_LEN 255 -#define TEST_FILE_SIZE 547 -#define CONFIG_APP_WIPE_STORAGE - -static uint8_t file_test_pattern[TEST_FILE_SIZE]; -static int lsdir(const char *path) -{ - int res; - struct fs_dir_t dirp; - static struct fs_dirent entry; - - fs_dir_t_init(&dirp); - - /* Verify fs_opendir() */ - res = fs_opendir(&dirp, path); - if (res) { - LOG_ERR("Error opening dir %s [%d]\n", path, res); - return res; - } - - LOG_PRINTK("\nListing dir %s ...\n", path); - for (;;) { - /* Verify fs_readdir() */ - res = fs_readdir(&dirp, &entry); - - /* entry.name[0] == 0 means end-of-dir */ - if (res || entry.name[0] == 0) { - if (res < 0) { - LOG_ERR("Error reading dir [%d]\n", res); - } - break; - } - - if (entry.type == FS_DIR_ENTRY_DIR) { - LOG_PRINTK("[DIR ] %s\n", entry.name); - } else { - LOG_PRINTK("[FILE] %s (size = %zu)\n", - entry.name, entry.size); - } - } - - /* Verify fs_closedir() */ - fs_closedir(&dirp); +#include +#include +#include + +#if defined(CONFIG_BOARD_ADAFRUIT_FEATHER_STM32F405) +#define SPI_FLASH_TEST_REGION_OFFSET 0xf000 +#elif defined(CONFIG_BOARD_ARTY_A7_ARM_DESIGNSTART_M1) || \ + defined(CONFIG_BOARD_ARTY_A7_ARM_DESIGNSTART_M3) +/* The FPGA bitstream is stored in the lower 536 sectors of the flash. */ +#define SPI_FLASH_TEST_REGION_OFFSET \ + DT_REG_SIZE(DT_NODE_BY_FIXED_PARTITION_LABEL(fpga_bitstream)) +#elif defined(CONFIG_BOARD_NPCX9M6F_EVB) || \ + defined(CONFIG_BOARD_NPCX7M6FB_EVB) +#define SPI_FLASH_TEST_REGION_OFFSET 0x7F000 +#else +#define SPI_FLASH_TEST_REGION_OFFSET 0xff000 +#endif +#define SPI_FLASH_SECTOR_SIZE 4096 - return res; -} +#if defined(CONFIG_FLASH_STM32_OSPI) || defined(CONFIG_FLASH_STM32_QSPI) +#define SPI_FLASH_MULTI_SECTOR_TEST +#endif -static int littlefs_increase_infile_value(char *fname) +void single_sector_test(const struct device *flash_dev) { - uint8_t boot_count = 0; - struct fs_file_t file; - int rc, ret; - - fs_file_t_init(&file); - rc = fs_open(&file, fname, FS_O_CREATE | FS_O_RDWR); - if (rc < 0) { - LOG_ERR("FAIL: open %s: %d", fname, rc); - return rc; - } - - rc = fs_read(&file, &boot_count, sizeof(boot_count)); - if (rc < 0) { - LOG_ERR("FAIL: read %s: [rd:%d]", fname, rc); - goto out; - } - LOG_PRINTK("%s read count:%u (bytes: %d)\n", fname, boot_count, rc); + const uint8_t expected[] = { 0x55, 0xaa, 0x66, 0x99 }; + const size_t len = sizeof(expected); + uint8_t buf[sizeof(expected)]; + int rc; - rc = fs_seek(&file, 0, FS_SEEK_SET); - if (rc < 0) { - LOG_ERR("FAIL: seek %s: %d", fname, rc); - goto out; - } + printf("\nPerform test on single sector"); + /* Write protection needs to be disabled before each write or + * erase, since the flash component turns on write protection + * automatically after completion of write and erase + * operations. + */ + printf("\nTest 1: Flash erase\n"); - boot_count += 1; - rc = fs_write(&file, &boot_count, sizeof(boot_count)); - if (rc < 0) { - LOG_ERR("FAIL: write %s: %d", fname, rc); - goto out; + /* Full flash erase if SPI_FLASH_TEST_REGION_OFFSET = 0 and + * SPI_FLASH_SECTOR_SIZE = flash size + */ + rc = flash_erase(flash_dev, SPI_FLASH_TEST_REGION_OFFSET, + SPI_FLASH_SECTOR_SIZE); + if (rc != 0) { + printf("Flash erase failed! %d\n", rc); + } else { + printf("Flash erase succeeded!\n"); } - LOG_PRINTK("%s write new boot count %u: [wr:%d]\n", fname, - boot_count, rc); + printf("\nTest 2: Flash write\n"); - out: - ret = fs_close(&file); - if (ret < 0) { - LOG_ERR("FAIL: close %s: %d", fname, ret); - return ret; + printf("Attempting to write %zu bytes\n", len); + rc = flash_write(flash_dev, SPI_FLASH_TEST_REGION_OFFSET, expected, len); + if (rc != 0) { + printf("Flash write failed! %d\n", rc); + return; } - return (rc < 0 ? rc : 0); -} - -static void incr_pattern(uint8_t *p, uint16_t size, uint8_t inc) -{ - uint8_t fill = 0x55; - - if (p[0] % 2 == 0) { - fill = 0xAA; + memset(buf, 0, len); + rc = flash_read(flash_dev, SPI_FLASH_TEST_REGION_OFFSET, buf, len); + if (rc != 0) { + printf("Flash read failed! %d\n", rc); + return; } - for (int i = 0; i < (size - 1); i++) { - if (i % 8 == 0) { - p[i] += inc; - } else { - p[i] = fill; + if (memcmp(expected, buf, len) == 0) { + printf("Data read matches data written. Good!!\n"); + } else { + const uint8_t *wp = expected; + const uint8_t *rp = buf; + const uint8_t *rpe = rp + len; + + printf("Data read does not match data written!!\n"); + while (rp < rpe) { + printf("%08x wrote %02x read %02x %s\n", + (uint32_t)(SPI_FLASH_TEST_REGION_OFFSET + (rp - buf)), + *wp, *rp, (*rp == *wp) ? "match" : "MISMATCH"); + ++rp; + ++wp; } } - - p[size - 1] += inc; } -static void init_pattern(uint8_t *p, uint16_t size) +#if defined SPI_FLASH_MULTI_SECTOR_TEST +void multi_sector_test(const struct device *flash_dev) { - uint8_t v = 0x1; - - memset(p, 0x55, size); - - for (int i = 0; i < size; i += 8) { - p[i] = v++; - } - - p[size - 1] = 0xAA; -} - -static void print_pattern(uint8_t *p, uint16_t size) -{ - int i, j = size / 16, k; - - for (k = 0, i = 0; k < j; i += 16, k++) { - LOG_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]); - LOG_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]); - - /* Mark 512B (sector) chunks of the test file */ - if ((k + 1) % 32 == 0) { - LOG_PRINTK("\n"); - } - } - - for (; i < size; i++) { - LOG_PRINTK("%02x ", p[i]); - } - - LOG_PRINTK("\n"); -} + const uint8_t expected[] = { 0x55, 0xaa, 0x66, 0x99 }; + const size_t len = sizeof(expected); + uint8_t buf[sizeof(expected)]; + int rc; -static int littlefs_binary_file_adj(char *fname) -{ - struct fs_dirent dirent; - struct fs_file_t file; - int rc, ret; + printf("\nPerform test on multiple consequtive sectors"); - /* - * Uncomment below line to force re-creation of the test pattern - * file on the littlefs FS. + /* Write protection needs to be disabled before each write or + * erase, since the flash component turns on write protection + * automatically after completion of write and erase + * operations. */ - /* fs_unlink(fname); */ - fs_file_t_init(&file); - - rc = fs_open(&file, fname, FS_O_CREATE | FS_O_RDWR); - if (rc < 0) { - LOG_ERR("FAIL: open %s: %d", fname, rc); - return rc; - } + printf("\nTest 1: Flash erase\n"); - rc = fs_stat(fname, &dirent); - if (rc < 0) { - LOG_ERR("FAIL: stat %s: %d", fname, rc); - goto out; - } - - /* Check if the file exists - if not just write the pattern */ - if (rc == 0 && dirent.type == FS_DIR_ENTRY_FILE && dirent.size == 0) { - LOG_INF("Test file: %s not found, create one!", - fname); - init_pattern(file_test_pattern, sizeof(file_test_pattern)); + /* Full flash erase if SPI_FLASH_TEST_REGION_OFFSET = 0 and + * SPI_FLASH_SECTOR_SIZE = flash size + * Erase 2 sectors for check for erase of consequtive sectors + */ + rc = flash_erase(flash_dev, SPI_FLASH_TEST_REGION_OFFSET, SPI_FLASH_SECTOR_SIZE * 2); + if (rc != 0) { + printf("Flash erase failed! %d\n", rc); } else { - rc = fs_read(&file, file_test_pattern, - sizeof(file_test_pattern)); - if (rc < 0) { - LOG_ERR("FAIL: read %s: [rd:%d]", - fname, rc); - goto out; + /* Read the content and check for erased */ + memset(buf, 0, len); + size_t offs = SPI_FLASH_TEST_REGION_OFFSET; + + while (offs < SPI_FLASH_TEST_REGION_OFFSET + 2 * SPI_FLASH_SECTOR_SIZE) { + rc = flash_read(flash_dev, offs, buf, len); + if (rc != 0) { + printf("Flash read failed! %d\n", rc); + return; + } + if (buf[0] != 0xff) { + printf("Flash erase failed at offset 0x%x got 0x%x\n", + offs, buf[0]); + return; + } + offs += SPI_FLASH_SECTOR_SIZE; } - incr_pattern(file_test_pattern, sizeof(file_test_pattern), 0x1); - } - - LOG_PRINTK("------ FILE: %s ------\n", fname); - print_pattern(file_test_pattern, sizeof(file_test_pattern)); - - rc = fs_seek(&file, 0, FS_SEEK_SET); - if (rc < 0) { - LOG_ERR("FAIL: seek %s: %d", fname, rc); - goto out; - } - - rc = fs_write(&file, file_test_pattern, sizeof(file_test_pattern)); - if (rc < 0) { - LOG_ERR("FAIL: write %s: %d", fname, rc); + printf("Flash erase succeeded!\n"); } - out: - ret = fs_close(&file); - if (ret < 0) { - LOG_ERR("FAIL: close %s: %d", fname, ret); - return ret; - } + printf("\nTest 2: Flash write\n"); - return (rc < 0 ? rc : 0); -} + size_t offs = SPI_FLASH_TEST_REGION_OFFSET; -static int littlefs_flash_erase(unsigned int id) -{ - const struct flash_area *pfa; - int rc; - - rc = flash_area_open(id, &pfa); - if (rc < 0) { - LOG_ERR("FAIL: unable to find flash area %u: %d\n", - id, rc); - return rc; - } + while (offs < SPI_FLASH_TEST_REGION_OFFSET + 2 * SPI_FLASH_SECTOR_SIZE) { + printf("Attempting to write %zu bytes at offset 0x%x\n", len, offs); + rc = flash_write(flash_dev, offs, expected, len); + if (rc != 0) { + printf("Flash write failed! %d\n", rc); + return; + } - LOG_PRINTK("Area %u at 0x%x on %s for %u bytes\n", - id, (unsigned int)pfa->fa_off, pfa->fa_dev->name, - (unsigned int)pfa->fa_size); + memset(buf, 0, len); + rc = flash_read(flash_dev, offs, buf, len); + if (rc != 0) { + printf("Flash read failed! %d\n", rc); + return; + } - /* Optional wipe flash contents */ - if (IS_ENABLED(CONFIG_APP_WIPE_STORAGE)) { - rc = flash_area_erase(pfa, 0, pfa->fa_size); - LOG_ERR("Erasing flash area ... %d", rc); + if (memcmp(expected, buf, len) == 0) { + printf("Data read matches data written. Good!!\n"); + } else { + const uint8_t *wp = expected; + const uint8_t *rp = buf; + const uint8_t *rpe = rp + len; + + printf("Data read does not match data written!!\n"); + while (rp < rpe) { + printf("%08x wrote %02x read %02x %s\n", + (uint32_t)(offs + (rp - buf)), + *wp, *rp, (*rp == *wp) ? "match" : "MISMATCH"); + ++rp; + ++wp; + } + } + offs += SPI_FLASH_SECTOR_SIZE; } - - flash_area_close(pfa); - return rc; } -#define PARTITION_NODE DT_NODELABEL(lfs1) - -FS_FSTAB_DECLARE_ENTRY(PARTITION_NODE); - -struct fs_mount_t *mountpoint = &FS_FSTAB_ENTRY(PARTITION_NODE);; - -static int littlefs_mount(struct fs_mount_t *mp) -{ - int rc; - - rc = littlefs_flash_erase((uintptr_t)mp->storage_dev); - if (rc < 0) { - return rc; - } - - /* Do not mount if auto-mount has been enabled */ -#if !DT_NODE_EXISTS(PARTITION_NODE) || \ - !(FSTAB_ENTRY_DT_MOUNT_FLAGS(PARTITION_NODE) & FS_MOUNT_FLAG_AUTOMOUNT) - rc = fs_mount(mp); - if (rc < 0) { - LOG_PRINTK("FAIL: mount id %" PRIuPTR " at %s: %d\n", - (uintptr_t)mp->storage_dev, mp->mnt_point, rc); - return rc; - } - LOG_PRINTK("%s mount: %d\n", mp->mnt_point, rc); -#else - LOG_PRINTK("%s automounted\n", mp->mnt_point); #endif - return 0; -} - - -int zsw_flash_test(void) +int asdf(void) { - char fname1[MAX_PATH_LEN]; - char fname2[MAX_PATH_LEN]; - struct fs_statvfs sbuf; - int rc; - - LOG_PRINTK("Sample program to r/w files on littlefs\n"); + const struct device *flash_dev = DEVICE_DT_GET(DT_ALIAS(spi_flash0)); - rc = littlefs_mount(mountpoint); - if (rc < 0) { + if (!device_is_ready(flash_dev)) { + printk("%s: device not ready.\n", flash_dev->name); return 0; } - snprintf(fname1, sizeof(fname1), "%s/boot_count", mountpoint->mnt_point); - snprintf(fname2, sizeof(fname2), "%s/pattern.bin", mountpoint->mnt_point); + printf("\n%s SPI flash testing\n", flash_dev->name); + printf("==========================\n"); - rc = fs_statvfs(mountpoint->mnt_point, &sbuf); - if (rc < 0) { - LOG_PRINTK("FAIL: statvfs: %d\n", rc); - goto out; - } - - LOG_PRINTK("%s: bsize = %lu ; frsize = %lu ;" - " blocks = %lu ; bfree = %lu\n", - mountpoint->mnt_point, - sbuf.f_bsize, sbuf.f_frsize, - sbuf.f_blocks, sbuf.f_bfree); - - rc = lsdir(mountpoint->mnt_point); - if (rc < 0) { - LOG_PRINTK("FAIL: lsdir %s: %d\n", mountpoint->mnt_point, rc); - goto out; - } -/* - rc = littlefs_increase_infile_value(fname1); - if (rc) { - goto out; - } - - rc = littlefs_binary_file_adj(fname2); - if (rc) { - goto out; - } -*/ - -out: - rc = fs_unmount(mountpoint); - LOG_PRINTK("%s unmount: %d\n", mountpoint->mnt_point, rc); + single_sector_test(flash_dev); +#if defined SPI_FLASH_MULTI_SECTOR_TEST + multi_sector_test(flash_dev); +#endif return 0; -} - - -//SYS_INIT(zsw_flash_test, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); +} \ No newline at end of file diff --git a/app/src/zsw_flash.h b/app/src/zsw_flash.h index 1d75712b..6c89a7b2 100644 --- a/app/src/zsw_flash.h +++ b/app/src/zsw_flash.h @@ -1,3 +1,6 @@ #pragma once +#include + int zsw_flash_test(void); +int zsw_flash_write_sector(int buf_idx, uint8_t* buf, int len); diff --git a/app/src/zsw_rtt_transfer.c b/app/src/zsw_rtt_transfer.c new file mode 100644 index 00000000..578a83fc --- /dev/null +++ b/app/src/zsw_rtt_transfer.c @@ -0,0 +1,51 @@ + +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(zsw_rtt_transfer, LOG_LEVEL_DBG); + +extern struct k_mutex rtt_term_mutex; + +struct uart_rtt_config { + uint8_t up_buffer[5000]; + uint8_t down_buffer[5000]; + uint8_t channel; + char* name; +}; + +static const struct uart_rtt_config config = { + .channel = 2, + .name = "ZSWChannelA" +}; + +static int zsw_rtt_transfer_init(void) +{ + // SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL + LOG_DBG("zsw_rtt_transfer_init"); + SEGGER_RTT_ConfigUpBuffer(config.channel, config.name, + config.up_buffer, sizeof(config.up_buffer), + SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL); + SEGGER_RTT_ConfigDownBuffer(config.channel, config.name, + config.down_buffer, sizeof(config.down_buffer), + SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL); + return 0; +} + +int zsw_rtt_transfer_read(uint8_t* buf, int len) +{ + //LOG_DBG("READ"); + return SEGGER_RTT_Read(config.channel, buf, len); + + //return -ENODATA; +} + +void zsw_rtt_transfer_write(uint8_t* buf, int len) +{ + LOG_DBG("WRITE"); + SEGGER_RTT_Write(config.channel, buf, len); +} + +SYS_INIT(zsw_rtt_transfer_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); \ No newline at end of file diff --git a/app/src/zsw_rtt_transfer.h b/app/src/zsw_rtt_transfer.h new file mode 100644 index 00000000..7624028e --- /dev/null +++ b/app/src/zsw_rtt_transfer.h @@ -0,0 +1,6 @@ + +#include + +int zsw_rtt_transfer_read(uint8_t* buf, int len); + +void zsw_rtt_transfer_write(uint8_t* buf, int len); \ No newline at end of file diff --git a/app/zephyr/module.yml b/app/zephyr/module.yml deleted file mode 100644 index 74a02aab..00000000 --- a/app/zephyr/module.yml +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (c) 2021 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -build: - # Path to the Kconfig file that will be sourced into Zephyr Kconfig tree under - # Zephyr > Modules > example-application. Path is relative from root of this - # repository. - # kconfig: Kconfig - # Path to the folder that contains the CMakeLists.txt file to be included by - # Zephyr build system. The `.` is the root of this repository. - cmake: . - settings: - # Additional roots for boards and DTS files. Zephyr will use the - # `/boards` for additional boards. The `.` is the root of this - # repository. - board_root: . - # Zephyr will use the `/dts` for additional dts files and - # `/dts/bindings` for additional dts binding files. The `.` is - # the root of this repository. - dts_root: . \ No newline at end of file