CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
Ardupilot

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: Ardupilot/ardupilot
Path: blob/master/libraries/AP_FlashIface/examples/jedec_test/jedec_test.cpp
Views: 1800
1
#include <AP_HAL/AP_HAL.h>
2
3
#if CONFIG_HAL_BOARD == HAL_BOARD_LINUX
4
5
const AP_HAL::HAL& hal = AP_HAL::get_HAL();
6
void setup() { }
7
8
void loop()
9
{
10
// the library simply panics if a JEDEC device can't be found. We
11
// can't really recover from that.
12
hal.console->printf("No JEDEC on linux\n");
13
hal.scheduler->delay(1000);
14
}
15
16
#else
17
18
#include <GCS_MAVLink/GCS_Dummy.h>
19
#include <AP_SerialManager/AP_SerialManager.h>
20
#include <AP_BoardConfig/AP_BoardConfig.h>
21
#include <AP_FlashIface/AP_FlashIface.h>
22
#include <stdio.h>
23
24
AP_FlashIface_JEDEC jedec_dev;
25
const AP_HAL::HAL& hal = AP_HAL::get_HAL();
26
27
void setup();
28
void loop();
29
30
GCS_Dummy _gcs;
31
32
33
#ifdef HAL_BOOTLOADER_BUILD
34
#define DELAY_MILLIS(x) do { chThdSleepMilliseconds(x); } while(0)
35
#define DELAY_MICROS(x) do { chThdSleepMicroseconds(x); } while(0)
36
#else
37
#define DELAY_MILLIS(x) do { hal.scheduler->delay(x); } while(0)
38
#define DELAY_MICROS(x) do { hal.scheduler->delay_microseconds(x); } while(0)
39
#endif
40
41
const AP_Param::GroupInfo GCS_MAVLINK_Parameters::var_info[] = {
42
AP_GROUPEND
43
};
44
45
static AP_SerialManager serial_manager;
46
static AP_BoardConfig board_config;
47
48
static UNUSED_FUNCTION void test_page_program()
49
{
50
uint8_t *data = new uint8_t[jedec_dev.get_page_size()];
51
if (data == nullptr) {
52
hal.console->printf("Failed to allocate data for program");
53
}
54
uint8_t *rdata = new uint8_t[jedec_dev.get_page_size()];
55
if (rdata == nullptr) {
56
hal.console->printf("Failed to allocate data for read");
57
}
58
59
// fill program data with its own address
60
for (uint32_t i = 0; i < jedec_dev.get_page_size(); i++) {
61
data[i] = i;
62
}
63
hal.console->printf("Writing Page #1\n");
64
uint32_t delay_us, timeout_us;
65
uint64_t start_time_us = AP_HAL::micros64();
66
if (!jedec_dev.start_program_page(0, data, delay_us, timeout_us)) {
67
hal.console->printf("Page write command failed\n");
68
return;
69
}
70
while (true) {
71
DELAY_MICROS(delay_us);
72
if (AP_HAL::micros64() > (start_time_us+delay_us)) {
73
if (!jedec_dev.is_device_busy()) {
74
hal.console->printf("Page Program Successful, elapsed %ld us\n", (unsigned long)(AP_HAL::micros64() - start_time_us));
75
break;
76
} else {
77
hal.console->printf("Typical page program time reached, Still Busy?!\n");
78
}
79
}
80
if (AP_HAL::micros64() > (start_time_us+timeout_us)) {
81
hal.console->printf("Page Program Timed out, elapsed %lld us\n", (unsigned long long)(AP_HAL::micros64() - start_time_us));
82
return;
83
}
84
}
85
if (!jedec_dev.read(0, rdata, jedec_dev.get_page_size())) {
86
hal.console->printf("Failed to read Flash page\n");
87
} else {
88
if (memcmp(data, rdata, jedec_dev.get_page_size()) != 0) {
89
hal.console->printf("Program Data Mismatch!\n");
90
} else {
91
hal.console->printf("Program Data Verified Good!\n");
92
}
93
}
94
95
// Now test XIP mode here as well
96
uint8_t *chip_data = nullptr;
97
if (!jedec_dev.start_xip_mode((void**)&chip_data)) {
98
hal.console->printf("Failed to setup XIP mode\n");
99
}
100
if (chip_data == nullptr) {
101
hal.console->printf("Invalid address!\n");
102
}
103
// Here comes the future!
104
if (memcmp(data, chip_data, jedec_dev.get_page_size()) != 0) {
105
hal.console->printf("Program Data Mismatch in XIP mode!\n");
106
} else {
107
hal.console->printf("Program Data Verified Good in XIP mode!\n");
108
}
109
jedec_dev.stop_xip_mode();
110
}
111
112
static UNUSED_FUNCTION void test_sector_erase()
113
{
114
uint32_t delay_ms, timeout_ms;
115
if (!jedec_dev.start_sector_erase(0, delay_ms, timeout_ms)) { // erase first sector
116
hal.console->printf("Sector erase command failed\n");
117
return;
118
}
119
uint32_t erase_start = AP_HAL::millis();
120
uint32_t next_check_ms = 0;
121
hal.console->printf("Erasing Sector #1 ");
122
while (true) {
123
if (AP_HAL::millis() > next_check_ms) {
124
hal.console->printf("\n");
125
if (!jedec_dev.is_device_busy()) {
126
if (next_check_ms == 0) {
127
hal.console->printf("Sector Erase happened too fast\n");
128
return;
129
}
130
hal.console->printf("Sector Erase Successful, elapsed %ld ms\n", (unsigned long)(AP_HAL::millis() - erase_start));
131
break;
132
} else {
133
hal.console->printf("Still busy erasing, elapsed %ld ms\n", (unsigned long)(AP_HAL::millis() - erase_start));
134
}
135
if ((AP_HAL::millis() - erase_start) > timeout_ms) {
136
hal.console->printf("Sector Erase Timed Out, elapsed %ld ms\n", (unsigned long)(AP_HAL::millis() - erase_start));
137
return;
138
}
139
next_check_ms = erase_start+delay_ms;
140
}
141
DELAY_MILLIS((delay_ms/100) + 10);
142
hal.console->printf("*");
143
}
144
if (!jedec_dev.verify_sector_erase(0)) {
145
hal.console->printf("Erase Verification Failed!\n");
146
} else {
147
hal.console->printf("Erase Verification Successful!\n");
148
}
149
}
150
151
static UNUSED_FUNCTION void test_mass_erase()
152
{
153
uint32_t delay_ms, timeout_ms;
154
if (!jedec_dev.start_mass_erase(delay_ms, timeout_ms)) {
155
hal.console->printf("Mass erase command failed\n");
156
return;
157
}
158
uint32_t erase_start = AP_HAL::millis();
159
uint32_t next_check_ms = 0;
160
hal.console->printf("Mass Erasing ");
161
while (true) {
162
if (AP_HAL::millis() > next_check_ms) {
163
hal.console->printf("\n");
164
if (!jedec_dev.is_device_busy()) {
165
if (next_check_ms == 0) {
166
hal.console->printf("Sector Erase happened too fast\n");
167
return;
168
}
169
hal.console->printf("Mass Erase Successful, elapsed %ld ms\n",(unsigned long)(AP_HAL::millis() - erase_start));
170
return;
171
} else {
172
hal.console->printf("Still busy erasing, elapsed %ld ms\n", (unsigned long)(AP_HAL::millis() - erase_start));
173
}
174
if ((AP_HAL::millis() - erase_start) > timeout_ms) {
175
hal.console->printf("Mass Erase Timed Out, elapsed %ld ms\n", (unsigned long)(AP_HAL::millis() - erase_start));
176
return;
177
}
178
next_check_ms = erase_start+delay_ms;
179
}
180
DELAY_MILLIS(delay_ms/100);
181
hal.console->printf("*");
182
}
183
}
184
185
void setup()
186
{
187
board_config.init();
188
serial_manager.init();
189
}
190
191
void loop()
192
{
193
// Start on user input
194
hal.console->printf("\n\n******************Starting Test********************\n");
195
jedec_dev.init();
196
test_sector_erase();
197
test_page_program();
198
// test_mass_erase();
199
hal.scheduler->delay(1000);
200
}
201
202
#endif
203
204
AP_HAL_MAIN();
205
206
207