From 32f91c4cb26997faaf0e68eea4f2e2a51f4399d1 Mon Sep 17 00:00:00 2001 From: Siddharth Purohit Date: Sun, 13 Jun 2021 21:07:09 +0530 Subject: [PATCH] AP_FlashIface: add jedec test using bootloader config --- .../AP_FlashIface/AP_FlashIface_JEDEC.cpp | 2 - .../examples/jedec_test_bl/jedec_test.cpp | 159 ++++++++++++++++++ .../examples/jedec_test_bl/wscript | 14 ++ 3 files changed, 173 insertions(+), 2 deletions(-) create mode 100644 libraries/AP_FlashIface/examples/jedec_test_bl/jedec_test.cpp create mode 100644 libraries/AP_FlashIface/examples/jedec_test_bl/wscript diff --git a/libraries/AP_FlashIface/AP_FlashIface_JEDEC.cpp b/libraries/AP_FlashIface/AP_FlashIface_JEDEC.cpp index 75e97d8153..0c5030bc5c 100644 --- a/libraries/AP_FlashIface/AP_FlashIface_JEDEC.cpp +++ b/libraries/AP_FlashIface/AP_FlashIface_JEDEC.cpp @@ -162,8 +162,6 @@ void AP_FlashIface_JEDEC::reset_device() { // Get chip out of XIP mode AP_HAL::QSPIDevice::CommandHeader cmd; - _dev->get_semaphore()->take_blocking(); - /* Single line CMD_RESET_MEMORY command.*/ cmd.cmd = CMD_RESET_ENABLE; cmd.cfg = AP_HAL::QSPI::CFG_CMD_MODE_ONE_LINE; diff --git a/libraries/AP_FlashIface/examples/jedec_test_bl/jedec_test.cpp b/libraries/AP_FlashIface/examples/jedec_test_bl/jedec_test.cpp new file mode 100644 index 0000000000..a6d4ed9241 --- /dev/null +++ b/libraries/AP_FlashIface/examples/jedec_test_bl/jedec_test.cpp @@ -0,0 +1,159 @@ +#include +#include +#include +#include + +AP_FlashIface_JEDEC jedec_dev; + +static UNUSED_FUNCTION void test_page_program() +{ + uint8_t *data = new uint8_t[jedec_dev.get_page_size()]; + if (data == nullptr) { + uprintf("Failed to allocate data for program"); + } + uint8_t *rdata = new uint8_t[jedec_dev.get_page_size()]; + if (rdata == nullptr) { + uprintf("Failed to allocate data for read"); + } + + // fill program data with its own adress + for (uint32_t i = 0; i < jedec_dev.get_page_size(); i++) { + data[i] = i; + } + uprintf("Writing Page #1\n"); + uint32_t delay_us, timeout_us; + uint64_t start_time_us = AP_HAL::micros64(); + if (!jedec_dev.start_program_page(0, data, delay_us, timeout_us)) { + uprintf("Page write command failed\n"); + return; + } + while (true) { + chThdSleep(chTimeUS2I(delay_us)); + if (AP_HAL::micros64() > (start_time_us+delay_us)) { + if (!jedec_dev.is_device_busy()) { + uprintf("Page Program Successful, elapsed %ld us\n", uint32_t(AP_HAL::micros64() - start_time_us)); + break; + } else { + uprintf("Typical page program time reached, Still Busy?!\n"); + } + } + if (AP_HAL::micros64() > (start_time_us+timeout_us)) { + uprintf("Page Program Timed out, elapsed %lld us\n", AP_HAL::micros64() - start_time_us); + return; + } + } + if (!jedec_dev.read(0, rdata, jedec_dev.get_page_size())) { + uprintf("Failed to read Flash page\n"); + } else { + if (memcmp(data, rdata, jedec_dev.get_page_size()) != 0) { + uprintf("Program Data Mismatch!\n"); + } else { + uprintf("Program Data Verified Good!\n"); + } + } + + // Now test XIP mode here as well + uint8_t *chip_data = nullptr; + if (!jedec_dev.start_xip_mode((void**)&chip_data)) { + uprintf("Failed to setup XIP mode\n"); + } + if (chip_data == nullptr) { + uprintf("Invalid address!\n"); + } + // Here comes the future! + if (memcmp(data, chip_data, jedec_dev.get_page_size()) != 0) { + uprintf("Program Data Mismatch in XIP mode!\n"); + } else { + uprintf("Program Data Verified Good in XIP mode!\n"); + } + jedec_dev.stop_xip_mode(); +} + +static UNUSED_FUNCTION void test_sector_erase() +{ + uint32_t delay_ms, timeout_ms; + if (!jedec_dev.start_sector_erase(0, delay_ms, timeout_ms)) { // erase first sector + uprintf("Sector erase command failed\n"); + return; + } + uint32_t erase_start = AP_HAL::millis(); + uint32_t next_check_ms = 0; + uprintf("Erasing Sector #1 "); + while (true) { + if (AP_HAL::millis() > next_check_ms) { + uprintf("\n"); + if (!jedec_dev.is_device_busy()) { + if (next_check_ms == 0) { + uprintf("Sector Erase happened too fast\n"); + return; + } + uprintf("Sector Erase Successful, elapsed %ld ms\n", AP_HAL::millis() - erase_start); + break; + } else { + uprintf("Still busy erasing, elapsed %ld ms\n", AP_HAL::millis() - erase_start); + } + if ((AP_HAL::millis() - erase_start) > timeout_ms) { + uprintf("Sector Erase Timed Out, elapsed %ld ms\n", AP_HAL::millis() - erase_start); + return; + } + next_check_ms = erase_start+delay_ms; + } + chThdSleep(chTimeMS2I((delay_ms/100) + 10)); + uprintf("*"); + } + if (!jedec_dev.verify_sector_erase(0)) { + uprintf("Erase Verification Failed!\n"); + } else { + uprintf("Erase Verification Successful!\n"); + } +} + +static UNUSED_FUNCTION void test_mass_erase() +{ + uint32_t delay_ms, timeout_ms; + if (!jedec_dev.start_mass_erase(delay_ms, timeout_ms)) { + uprintf("Mass erase command failed\n"); + return; + } + uint32_t erase_start = AP_HAL::millis(); + uint32_t next_check_ms = 0; + uprintf("Mass Erasing "); + while (true) { + if (AP_HAL::millis() > next_check_ms) { + uprintf("\n"); + if (!jedec_dev.is_device_busy()) { + if (next_check_ms == 0) { + uprintf("Sector Erase happened too fast\n"); + return; + } + uprintf("Mass Erase Successful, elapsed %ld ms\n", AP_HAL::millis() - erase_start); + return; + } else { + uprintf("Still busy erasing, elapsed %ld ms\n", AP_HAL::millis() - erase_start); + } + if ((AP_HAL::millis() - erase_start) > timeout_ms) { + uprintf("Mass Erase Timed Out, elapsed %ld ms\n", AP_HAL::millis() - erase_start); + return; + } + next_check_ms = erase_start+delay_ms; + } + chThdSleep(chTimeMS2I(delay_ms/100)); + uprintf("*"); + } +} + +int main() +{ + init_uarts(); + + while (true) { + // Start on user input + while (cin(0) < 0) {} + uprintf("\n\n******************Starting Test********************\n"); + jedec_dev.init(); + test_sector_erase(); + test_page_program(); + // test_mass_erase(); + chThdSleep(chTimeMS2I(1000)); + } +} diff --git a/libraries/AP_FlashIface/examples/jedec_test_bl/wscript b/libraries/AP_FlashIface/examples/jedec_test_bl/wscript new file mode 100644 index 0000000000..275db00256 --- /dev/null +++ b/libraries/AP_FlashIface/examples/jedec_test_bl/wscript @@ -0,0 +1,14 @@ +#!/usr/bin/env python +# encoding: utf-8 + +def build(bld): + if bld.env.BOOTLOADER: + bld.ap_program( + source=['../../../../Tools/AP_Bootloader/support.cpp', 'jedec_test.cpp'], + use=['ap','JEDEC_libs'], + program_groups='examples', + includes=bld.env.SRCROOT + '/Tools/AP_Bootloader/' + ) + bld.ap_stlib(name= 'JEDEC_libs', + ap_vehicle='AP_Bootloader', + ap_libraries= ['AP_FlashIface', 'AP_HAL_Empty'])