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/AP_FlashIface_JEDEC.h
Views: 1798
1
/*
2
* This file is free software: you can redistribute it and/or modify it
3
* under the terms of the GNU General Public License as published by the
4
* Free Software Foundation, either version 3 of the License, or
5
* (at your option) any later version.
6
*
7
* This file is distributed in the hope that it will be useful, but
8
* WITHOUT ANY WARRANTY; without even the implied warranty of
9
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
* See the GNU General Public License for more details.
11
*
12
* You should have received a copy of the GNU General Public License along
13
* with this program. If not, see <http://www.gnu.org/licenses/>.
14
*
15
* Code by
16
* Andy Piper
17
* Siddharth Bharat Purohit, Cubepilot Pty. Ltd.
18
*/
19
/*
20
Implements Common Flash Interface Driver based on
21
Open Standard Published by JEDEC
22
*/
23
24
#include "AP_FlashIface_Abstract.h"
25
26
27
class AP_FlashIface_JEDEC : public AP_FlashIface
28
{
29
public:
30
bool init() override;
31
32
/**
33
* @details Read data from flash chip.
34
*
35
* @param[in] offset address offset from where to start the read
36
* @param[out] data data to be read from the device
37
* @param[in] size size of the data to be read
38
* @return The operation status.
39
* @retval false if the operation failed.
40
* @retval true if the operation succeeded.
41
*
42
*/
43
bool read(uint32_t offset, uint8_t *data, uint32_t size) override;
44
45
46
/**
47
* @details Gets number bytes that can be written in one go (page size).
48
*
49
* @return page size in bytes.
50
*
51
*/
52
uint32_t get_page_size() const override
53
{
54
return _desc.page_size;
55
}
56
57
/**
58
* @details Gets number pages, each page can written in one go
59
*
60
* @return Number of pages.
61
*
62
*/
63
uint32_t get_page_count() const override
64
{
65
return _desc.page_count;
66
}
67
68
/**
69
* @details Sends command to start programming a page of the chip.
70
*
71
* @param[in] page Page number to be written to
72
* @param[in] data data to be written
73
* @param[out] delay_us Time to wait until next is_device_busy call
74
* @param[out] timeout_us Time after which the erase should be timedout,
75
* should be reset at every call.
76
* @return The operation status.
77
* @retval false if the operation failed.
78
* @retval true if the operation succeeded.
79
*
80
*/
81
bool start_program_page(uint32_t page, const uint8_t *data, uint32_t &delay_us, uint32_t &timeout_us) override;
82
83
/**
84
* @details Tries to program as much as possible starting from the offset
85
* until size. User needs to call this as many times as needed
86
* taking already programmed bytes into account.
87
*
88
* @param[in] offset address offset for program
89
* @param[in] data data to be programmed
90
* @param[in] size size desired to be programmed
91
* @param[out] programming number of bytes programming, taking care of the limits
92
* @param[out] delay_us Time to wait until program typically finishes
93
* @param[out] timeout_us Time by which current program should have timedout.
94
* @return The operation status.
95
* @retval false if the operation failed.
96
* @retval true if the operation succeeded.
97
*
98
*/
99
bool start_program_offset(uint32_t offset, const uint8_t* data, uint32_t size, uint32_t &programming,
100
uint32_t &delay_us, uint32_t &timeout_us) override;
101
102
// Erase Methods
103
104
/**
105
* @details Sends command to erase the entire chip.
106
*
107
* @param[out] delay_ms Time to wait until next is_device_busy call
108
* @param[out] timeout_ms Time by which the erase should have timedout
109
*
110
* @return The operation status.
111
* @retval false if the operation failed.
112
* @retval true if the operation succeeded.
113
*
114
*/
115
bool start_mass_erase(uint32_t &delay_ms, uint32_t &timeout_ms) override;
116
117
/**
118
* @details Gets number bytes that can erased in one go(sector size)
119
*
120
* @return Sector size in bytes.
121
*
122
*/
123
uint32_t get_sector_size() const override
124
{
125
return _desc.sector_size;
126
}
127
128
/**
129
* @details Gets number of sectors, each sector can be erased in one go
130
*
131
* @return Number of sectors.
132
*
133
*/
134
uint32_t get_sector_count() const override
135
{
136
return _desc.sector_count;
137
}
138
139
/**
140
* @details minimum number of bytes that can be erased
141
*
142
* @return Number of bytes.
143
*
144
*/
145
uint32_t min_erase_size() const override
146
{
147
return _desc.min_erase_size;
148
}
149
150
151
/**
152
* @details Sends command to erase a sector of the chip.
153
*
154
* @param[in] sector Sector number to be erased
155
* @param[out] delay_ms Time to wait until next is_device_busy call
156
* @param[out] timeout_ms Time by which the erase should have timedout
157
*
158
* @return The operation status.
159
* @retval false if the operation failed.
160
* @retval true if the operation succeeded.
161
*
162
*/
163
bool start_sector_erase(uint32_t sector, uint32_t &delay_ms, uint32_t &timeout_ms) override;
164
165
/**
166
* @details Tries to erase as much as possible starting from the offset
167
* until size. User needs to call this as many times as needed
168
* taking already erased bytes into account, until desired erase
169
* has taken place
170
*
171
* @param[in] offset address offset for erase
172
* @param[in] size size desired to be erased
173
* @param[out] erasing number of bytes erasing
174
* @param[out] delay_ms Time to wait until next is_device_busy call
175
* @param[out] timeout_ms Time by which the erase should have timedout
176
*
177
* @return The operation status.
178
* @retval false if the operation failed.
179
* @retval true if the operation succeeded.
180
*
181
*/
182
bool start_erase_offset(uint32_t offset, uint32_t size, uint32_t &erasing,
183
uint32_t &delay_ms, uint32_t &timeout_ms) override;
184
185
186
/**
187
* @details Check if selected sector is erased.
188
*
189
* @param[in] sector sector for which to check erase
190
* @return The operation status.
191
* @retval false if the operation failed.
192
* @retval true if the operation succeeded.
193
*
194
*/
195
bool verify_sector_erase(uint32_t sector) override;
196
197
198
/**
199
* @details Check if the device is busy.
200
*
201
* @return device busy with last op.
202
*
203
* @retval false if the device is ready.
204
* @retval true if the device is busy.
205
*
206
*/
207
bool is_device_busy() override;
208
209
210
/**
211
* @details Starts execution in place mode
212
*
213
* @return if successfully entered XIP mode.
214
*
215
* @retval false the device failed to enter XIP mode.
216
* @retval true the device has entered XIP mode.
217
*
218
*/
219
bool start_xip_mode(void** addr) override;
220
221
bool stop_xip_mode() override;
222
protected:
223
void reset_device();
224
225
// Does initial configuration to bring up and setup chip
226
bool detect_device();
227
228
// Configures device to normal working state, currently 4-4-4 WSPI
229
bool configure_device();
230
231
// Enables commands that modify flash data or settings
232
bool write_enable();
233
234
// Disables commands that modify flash data or settings
235
bool write_disable();
236
237
// wait for the chip to be ready for the next instruction
238
void wait_ready();
239
240
// Read modify write register
241
bool modify_reg(uint8_t read_ins, uint8_t write_ins,
242
uint8_t mask, uint8_t va_list);
243
244
// reads a register value of chip using instruction
245
bool read_reg(uint8_t read_ins, uint8_t &read_val);
246
247
// sends instruction to write a register value in the chip
248
bool write_reg(uint8_t read_ins, uint8_t write_val);
249
250
// Sends WSPI command without data
251
bool send_cmd(uint8_t ins);
252
253
// Is device in wide spi mode
254
enum class WSPIMode {
255
NormalSPI,
256
QuadSPI,
257
OctoSPI
258
} _wide_spi_mode;
259
260
AP_HAL::OwnPtr<AP_HAL::WSPIDevice> _dev;
261
262
enum xip_entry_methods {
263
XIP_ENTRY_METHOD_1,
264
XIP_ENTRY_METHOD_2,
265
XIP_ENTRY_METHOD_3
266
};
267
268
// Device description extracted from SFDP
269
struct device_desc {
270
uint16_t param_rev; //parameter revision
271
uint8_t param_table_len; // size of parameter table
272
uint32_t param_table_pointer; // location of parameter table
273
uint32_t flash_size; // size of flash in bytes
274
uint32_t page_size; // maximum size that can be written in one transaction
275
uint32_t page_count; // number of pages each of page size
276
uint32_t sector_size; // maximum number of bytes that can be erased outside of mass erase
277
uint32_t sector_count; // number of sectors
278
uint32_t min_erase_size; // minimum amount of bytes that can be erased
279
struct {
280
uint8_t ins; // instruction for the erase
281
uint32_t size; // number of bytes that will be erased
282
uint32_t delay_ms; // typical time this command will finish
283
uint32_t timeout_ms; // time after which the erase cmd caller should time
284
} erase_type[4];
285
uint32_t mass_erase_delay_ms; // typical time taken while mass erase
286
uint32_t mass_erase_timeout_ms; // time after which mass erase cmd caller should timeout
287
uint8_t write_enable_ins; // instruction to allow enabling modification of register and data
288
uint32_t page_prog_delay_us; // time taken to write a page worth of data to flash
289
uint32_t page_prog_timeout_us; // time after which the page program caller should timeout
290
uint8_t fast_read_ins; // instruction to do fast read, i.e. read any number of bytes in single trx
291
uint8_t fast_read_dummy_cycles; // number of dummy cycles after which the chip will respond with data
292
uint8_t quad_mode_ins; // instruction to enter 4-4-4 mode
293
uint8_t wide_mode_enable;
294
bool quad_mode_rmw_seq; // use Read modify write sequence to enter 4-4-4 mode supported or not
295
uint8_t status_read_ins; // read status of the chip, gets us if busy writing/erasing
296
bool legacy_status_polling; // check if legacy status polling supported or not
297
bool is_xip_supported; // is execution in place or 0-4-4 mode supported
298
uint8_t fast_read_mode_clocks;
299
xip_entry_methods entry_method;
300
} _desc;
301
302
uint8_t _dev_list_idx;
303
bool initialised;
304
bool write_enable_called;
305
};
306
307
308