2021-05-29 16:51:33 -03:00
|
|
|
#include <AP_HAL/AP_HAL.h>
|
2022-08-18 22:56:22 -03:00
|
|
|
|
|
|
|
#if CONFIG_HAL_BOARD == HAL_BOARD_LINUX
|
|
|
|
|
|
|
|
const AP_HAL::HAL& hal = AP_HAL::get_HAL();
|
|
|
|
void setup() { }
|
|
|
|
|
|
|
|
void loop()
|
|
|
|
{
|
|
|
|
// the library simply panics if a JEDEC device can't be found. We
|
|
|
|
// can't really recover from that.
|
|
|
|
hal.console->printf("No JEDEC on linux\n");
|
|
|
|
hal.scheduler->delay(1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
2021-06-13 13:14:16 -03:00
|
|
|
#include <GCS_MAVLink/GCS_Dummy.h>
|
|
|
|
#include <AP_SerialManager/AP_SerialManager.h>
|
|
|
|
#include <AP_BoardConfig/AP_BoardConfig.h>
|
2021-05-29 16:51:33 -03:00
|
|
|
#include <AP_FlashIface/AP_FlashIface.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
AP_FlashIface_JEDEC jedec_dev;
|
2021-06-13 13:14:16 -03:00
|
|
|
const AP_HAL::HAL& hal = AP_HAL::get_HAL();
|
|
|
|
|
|
|
|
void setup();
|
|
|
|
void loop();
|
|
|
|
|
|
|
|
GCS_Dummy _gcs;
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef HAL_BOOTLOADER_BUILD
|
|
|
|
#define DELAY_MILLIS(x) do { chThdSleepMilliseconds(x); } while(0)
|
|
|
|
#define DELAY_MICROS(x) do { chThdSleepMicroseconds(x); } while(0)
|
|
|
|
#else
|
|
|
|
#define DELAY_MILLIS(x) do { hal.scheduler->delay(x); } while(0)
|
|
|
|
#define DELAY_MICROS(x) do { hal.scheduler->delay_microseconds(x); } while(0)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
const AP_Param::GroupInfo GCS_MAVLINK_Parameters::var_info[] = {
|
|
|
|
AP_GROUPEND
|
|
|
|
};
|
|
|
|
|
|
|
|
static AP_SerialManager serial_manager;
|
|
|
|
static AP_BoardConfig board_config;
|
2021-05-29 16:51:33 -03:00
|
|
|
|
|
|
|
static UNUSED_FUNCTION void test_page_program()
|
|
|
|
{
|
|
|
|
uint8_t *data = new uint8_t[jedec_dev.get_page_size()];
|
|
|
|
if (data == nullptr) {
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Failed to allocate data for program");
|
2021-05-29 16:51:33 -03:00
|
|
|
}
|
|
|
|
uint8_t *rdata = new uint8_t[jedec_dev.get_page_size()];
|
|
|
|
if (rdata == nullptr) {
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Failed to allocate data for read");
|
2021-05-29 16:51:33 -03:00
|
|
|
}
|
|
|
|
|
2023-10-11 04:41:52 -03:00
|
|
|
// fill program data with its own address
|
2021-05-29 16:51:33 -03:00
|
|
|
for (uint32_t i = 0; i < jedec_dev.get_page_size(); i++) {
|
|
|
|
data[i] = i;
|
|
|
|
}
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Writing Page #1\n");
|
2021-05-29 16:51:33 -03:00
|
|
|
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)) {
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Page write command failed\n");
|
2021-05-29 16:51:33 -03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
while (true) {
|
2021-06-13 13:14:16 -03:00
|
|
|
DELAY_MICROS(delay_us);
|
2021-05-29 16:51:33 -03:00
|
|
|
if (AP_HAL::micros64() > (start_time_us+delay_us)) {
|
|
|
|
if (!jedec_dev.is_device_busy()) {
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Page Program Successful, elapsed %ld us\n", (unsigned long)(AP_HAL::micros64() - start_time_us));
|
2021-05-29 16:51:33 -03:00
|
|
|
break;
|
|
|
|
} else {
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Typical page program time reached, Still Busy?!\n");
|
2021-05-29 16:51:33 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (AP_HAL::micros64() > (start_time_us+timeout_us)) {
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Page Program Timed out, elapsed %lld us\n", (unsigned long long)(AP_HAL::micros64() - start_time_us));
|
2021-05-29 16:51:33 -03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!jedec_dev.read(0, rdata, jedec_dev.get_page_size())) {
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Failed to read Flash page\n");
|
2021-05-29 16:51:33 -03:00
|
|
|
} else {
|
|
|
|
if (memcmp(data, rdata, jedec_dev.get_page_size()) != 0) {
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Program Data Mismatch!\n");
|
2021-05-29 16:51:33 -03:00
|
|
|
} else {
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Program Data Verified Good!\n");
|
2021-05-29 16:51:33 -03:00
|
|
|
}
|
|
|
|
}
|
2021-06-08 04:45:05 -03:00
|
|
|
|
|
|
|
// Now test XIP mode here as well
|
|
|
|
uint8_t *chip_data = nullptr;
|
|
|
|
if (!jedec_dev.start_xip_mode((void**)&chip_data)) {
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Failed to setup XIP mode\n");
|
2021-06-08 04:45:05 -03:00
|
|
|
}
|
|
|
|
if (chip_data == nullptr) {
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Invalid address!\n");
|
2021-06-08 04:45:05 -03:00
|
|
|
}
|
|
|
|
// Here comes the future!
|
|
|
|
if (memcmp(data, chip_data, jedec_dev.get_page_size()) != 0) {
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Program Data Mismatch in XIP mode!\n");
|
2021-06-08 04:45:05 -03:00
|
|
|
} else {
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Program Data Verified Good in XIP mode!\n");
|
2021-06-08 04:45:05 -03:00
|
|
|
}
|
|
|
|
jedec_dev.stop_xip_mode();
|
2021-05-29 16:51:33 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Sector erase command failed\n");
|
2021-05-29 16:51:33 -03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
uint32_t erase_start = AP_HAL::millis();
|
|
|
|
uint32_t next_check_ms = 0;
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Erasing Sector #1 ");
|
2021-05-29 16:51:33 -03:00
|
|
|
while (true) {
|
|
|
|
if (AP_HAL::millis() > next_check_ms) {
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("\n");
|
2021-05-29 16:51:33 -03:00
|
|
|
if (!jedec_dev.is_device_busy()) {
|
|
|
|
if (next_check_ms == 0) {
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Sector Erase happened too fast\n");
|
2021-05-29 16:51:33 -03:00
|
|
|
return;
|
|
|
|
}
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Sector Erase Successful, elapsed %ld ms\n", (unsigned long)(AP_HAL::millis() - erase_start));
|
2021-05-29 16:51:33 -03:00
|
|
|
break;
|
|
|
|
} else {
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Still busy erasing, elapsed %ld ms\n", (unsigned long)(AP_HAL::millis() - erase_start));
|
2021-05-29 16:51:33 -03:00
|
|
|
}
|
|
|
|
if ((AP_HAL::millis() - erase_start) > timeout_ms) {
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Sector Erase Timed Out, elapsed %ld ms\n", (unsigned long)(AP_HAL::millis() - erase_start));
|
2021-05-29 16:51:33 -03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
next_check_ms = erase_start+delay_ms;
|
|
|
|
}
|
2021-06-13 13:14:16 -03:00
|
|
|
DELAY_MILLIS((delay_ms/100) + 10);
|
|
|
|
hal.console->printf("*");
|
2021-05-29 16:51:33 -03:00
|
|
|
}
|
|
|
|
if (!jedec_dev.verify_sector_erase(0)) {
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Erase Verification Failed!\n");
|
2021-05-29 16:51:33 -03:00
|
|
|
} else {
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Erase Verification Successful!\n");
|
2021-05-29 16:51:33 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static UNUSED_FUNCTION void test_mass_erase()
|
|
|
|
{
|
|
|
|
uint32_t delay_ms, timeout_ms;
|
|
|
|
if (!jedec_dev.start_mass_erase(delay_ms, timeout_ms)) {
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Mass erase command failed\n");
|
2021-05-29 16:51:33 -03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
uint32_t erase_start = AP_HAL::millis();
|
|
|
|
uint32_t next_check_ms = 0;
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Mass Erasing ");
|
2021-05-29 16:51:33 -03:00
|
|
|
while (true) {
|
|
|
|
if (AP_HAL::millis() > next_check_ms) {
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("\n");
|
2021-05-29 16:51:33 -03:00
|
|
|
if (!jedec_dev.is_device_busy()) {
|
|
|
|
if (next_check_ms == 0) {
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Sector Erase happened too fast\n");
|
2021-05-29 16:51:33 -03:00
|
|
|
return;
|
|
|
|
}
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Mass Erase Successful, elapsed %ld ms\n",(unsigned long)(AP_HAL::millis() - erase_start));
|
2021-05-29 16:51:33 -03:00
|
|
|
return;
|
|
|
|
} else {
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Still busy erasing, elapsed %ld ms\n", (unsigned long)(AP_HAL::millis() - erase_start));
|
2021-05-29 16:51:33 -03:00
|
|
|
}
|
|
|
|
if ((AP_HAL::millis() - erase_start) > timeout_ms) {
|
2021-06-13 13:14:16 -03:00
|
|
|
hal.console->printf("Mass Erase Timed Out, elapsed %ld ms\n", (unsigned long)(AP_HAL::millis() - erase_start));
|
2021-05-29 16:51:33 -03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
next_check_ms = erase_start+delay_ms;
|
|
|
|
}
|
2021-06-13 13:14:16 -03:00
|
|
|
DELAY_MILLIS(delay_ms/100);
|
|
|
|
hal.console->printf("*");
|
2021-05-29 16:51:33 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-13 13:14:16 -03:00
|
|
|
void setup()
|
2021-05-29 16:51:33 -03:00
|
|
|
{
|
2021-06-13 13:14:16 -03:00
|
|
|
board_config.init();
|
|
|
|
serial_manager.init();
|
|
|
|
}
|
2021-05-29 16:51:33 -03:00
|
|
|
|
2021-06-13 13:14:16 -03:00
|
|
|
void loop()
|
|
|
|
{
|
|
|
|
// Start on user input
|
|
|
|
hal.console->printf("\n\n******************Starting Test********************\n");
|
|
|
|
jedec_dev.init();
|
|
|
|
test_sector_erase();
|
|
|
|
test_page_program();
|
|
|
|
// test_mass_erase();
|
|
|
|
hal.scheduler->delay(1000);
|
2021-05-29 16:51:33 -03:00
|
|
|
}
|
2021-06-13 13:14:16 -03:00
|
|
|
|
2022-08-18 22:56:22 -03:00
|
|
|
#endif
|
|
|
|
|
2021-06-13 13:14:16 -03:00
|
|
|
AP_HAL_MAIN();
|
2022-08-18 22:56:22 -03:00
|
|
|
|