Skip to content

Commit c9ab4d7

Browse files
partitioning tested and working
1 parent 6058ecd commit c9ab4d7

File tree

4 files changed

+691
-1
lines changed

4 files changed

+691
-1
lines changed

libraries/QSPI/QSPI.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#define QSPI_FLASH_DEVICE DEVICE_DT_GET(QSPI_FLASH_NODE)
77
#else
88
#define QSPI_FLASH_DEVICE NULL
9-
#warning "QSPI flash device not found in device tree"
9+
#warning "No QSPI flash available on this board"
1010
#endif
1111

1212
QSPIClass::QSPIClass() : flash_dev(nullptr), initialized(false) {
@@ -119,6 +119,10 @@ bool QSPIClass::isValidAddress(uint32_t address, size_t size) {
119119
return (address + size <= flash_size);
120120
}
121121

122+
const struct device* QSPIClass::getDevice() {
123+
return flash_dev;
124+
}
125+
122126
void QSPIClass::end() {
123127
flash_dev = nullptr;
124128
initialized = false;

libraries/QSPI/QSPI.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ class QSPIClass {
3838
// Utility functions
3939
bool isValidAddress(uint32_t address, size_t size = 1);
4040

41+
// Get the underlying Zephyr device (for filesystem/advanced usage)
42+
const struct device* getDevice();
43+
4144
// End/deinitialize
4245
void end();
4346

Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
/*
2+
QSPI Filesystem Example
3+
4+
This example demonstrates how to use the QSPI library with LittleFS
5+
filesystem to store and retrieve files on external QSPI flash memory.
6+
7+
Features:
8+
- Mount LittleFS on QSPI flash
9+
- Create, write, and read files
10+
- List directory contents
11+
- Check filesystem statistics
12+
13+
Note:
14+
- QSPI flash must be configured in the board's device tree overlay
15+
- Zephyr CONFIG_FILE_SYSTEM=y and CONFIG_FILE_SYSTEM_LITTLEFS=y must be enabled
16+
- Add to prj.conf:
17+
CONFIG_FILE_SYSTEM=y
18+
CONFIG_FILE_SYSTEM_LITTLEFS=y
19+
CONFIG_FILE_SYSTEM_MAX_FILE_NAME=128
20+
*/
21+
22+
#include <QSPI.h>
23+
#include <zephyr/fs/fs.h>
24+
#include <zephyr/fs/littlefs.h>
25+
#include <zephyr/storage/flash_map.h>
26+
27+
// Mount point for the filesystem
28+
#define MOUNT_POINT "/qspi"
29+
30+
// LittleFS configuration
31+
FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(storage);
32+
static struct fs_mount_t mp = {
33+
.type = FS_LITTLEFS,
34+
.fs_data = &storage,
35+
.mnt_point = MOUNT_POINT,
36+
};
37+
38+
void setup() {
39+
Serial.begin(115200);
40+
while (!Serial) {
41+
delay(10);
42+
}
43+
44+
Serial.println("QSPI Filesystem Example");
45+
Serial.println("========================\n");
46+
47+
// Initialize QSPI flash
48+
if (!QSPI.begin()) {
49+
Serial.println("Failed to initialize QSPI flash!");
50+
while (1) {
51+
delay(1000);
52+
}
53+
}
54+
55+
Serial.println("QSPI flash initialized successfully");
56+
Serial.print("Flash size: ");
57+
Serial.print(QSPI.getFlashSize() / 1024);
58+
Serial.println(" KB\n");
59+
60+
// Mount the filesystem
61+
Serial.print("Mounting LittleFS at " MOUNT_POINT "... ");
62+
int ret = fs_mount(&mp);
63+
64+
if (ret == 0) {
65+
Serial.println("OK");
66+
} else if (ret == -EBUSY) {
67+
Serial.println("Already mounted");
68+
} else {
69+
Serial.print("FAILED (");
70+
Serial.print(ret);
71+
Serial.println(")");
72+
Serial.println("Note: First mount may fail - filesystem might need formatting");
73+
Serial.println("Try erasing the flash first or format the filesystem");
74+
while (1) {
75+
delay(1000);
76+
}
77+
}
78+
79+
// Show filesystem statistics
80+
printFilesystemStats();
81+
82+
// Test filesystem operations
83+
testFileOperations();
84+
85+
// List files
86+
listFiles();
87+
}
88+
89+
void loop() {
90+
// Nothing to do in loop
91+
delay(1000);
92+
}
93+
94+
void printFilesystemStats() {
95+
struct fs_statvfs stats;
96+
int ret = fs_statvfs(MOUNT_POINT, &stats);
97+
98+
if (ret == 0) {
99+
Serial.println("\nFilesystem Statistics:");
100+
Serial.print(" Block size: ");
101+
Serial.print(stats.f_bsize);
102+
Serial.println(" bytes");
103+
104+
Serial.print(" Total blocks: ");
105+
Serial.println(stats.f_blocks);
106+
107+
Serial.print(" Free blocks: ");
108+
Serial.println(stats.f_bfree);
109+
110+
uint32_t total_kb = (stats.f_blocks * stats.f_bsize) / 1024;
111+
uint32_t free_kb = (stats.f_bfree * stats.f_bsize) / 1024;
112+
uint32_t used_kb = total_kb - free_kb;
113+
114+
Serial.print(" Total space: ");
115+
Serial.print(total_kb);
116+
Serial.println(" KB");
117+
118+
Serial.print(" Used space: ");
119+
Serial.print(used_kb);
120+
Serial.println(" KB");
121+
122+
Serial.print(" Free space: ");
123+
Serial.print(free_kb);
124+
Serial.println(" KB\n");
125+
} else {
126+
Serial.print("Failed to get filesystem stats: ");
127+
Serial.println(ret);
128+
}
129+
}
130+
131+
void testFileOperations() {
132+
Serial.println("Testing File Operations:");
133+
Serial.println("------------------------");
134+
135+
// Create and write to a file
136+
const char *filepath = MOUNT_POINT "/test.txt";
137+
const char *data = "Hello from QSPI filesystem!\nThis is a test file.\n";
138+
139+
Serial.print("Writing file: ");
140+
Serial.print(filepath);
141+
Serial.print("... ");
142+
143+
struct fs_file_t file;
144+
fs_file_t_init(&file);
145+
146+
int ret = fs_open(&file, filepath, FS_O_CREATE | FS_O_WRITE);
147+
if (ret < 0) {
148+
Serial.print("FAILED to open (");
149+
Serial.print(ret);
150+
Serial.println(")");
151+
return;
152+
}
153+
154+
ssize_t written = fs_write(&file, data, strlen(data));
155+
fs_close(&file);
156+
157+
if (written == strlen(data)) {
158+
Serial.print("OK (");
159+
Serial.print(written);
160+
Serial.println(" bytes)");
161+
} else {
162+
Serial.println("FAILED");
163+
return;
164+
}
165+
166+
// Read the file back
167+
Serial.print("Reading file... ");
168+
char read_buffer[128];
169+
memset(read_buffer, 0, sizeof(read_buffer));
170+
171+
fs_file_t_init(&file);
172+
ret = fs_open(&file, filepath, FS_O_READ);
173+
if (ret < 0) {
174+
Serial.print("FAILED to open (");
175+
Serial.print(ret);
176+
Serial.println(")");
177+
return;
178+
}
179+
180+
ssize_t bytes_read = fs_read(&file, read_buffer, sizeof(read_buffer) - 1);
181+
fs_close(&file);
182+
183+
if (bytes_read > 0) {
184+
Serial.print("OK (");
185+
Serial.print(bytes_read);
186+
Serial.println(" bytes)");
187+
Serial.println("\nFile contents:");
188+
Serial.println("---");
189+
Serial.print(read_buffer);
190+
Serial.println("---\n");
191+
} else {
192+
Serial.println("FAILED");
193+
}
194+
195+
// Write a second file with sensor data simulation
196+
const char *datafile = MOUNT_POINT "/sensor_data.txt";
197+
Serial.print("Creating sensor data file... ");
198+
199+
fs_file_t_init(&file);
200+
ret = fs_open(&file, datafile, FS_O_CREATE | FS_O_WRITE);
201+
if (ret == 0) {
202+
// Simulate writing sensor readings
203+
for (int i = 0; i < 10; i++) {
204+
char line[64];
205+
snprintf(line, sizeof(line), "Reading %d: Temperature=%.1f C, Humidity=%.1f%%\n",
206+
i, 20.0 + i * 0.5, 45.0 + i * 1.2);
207+
fs_write(&file, line, strlen(line));
208+
}
209+
fs_close(&file);
210+
Serial.println("OK");
211+
} else {
212+
Serial.println("FAILED");
213+
}
214+
}
215+
216+
void listFiles() {
217+
Serial.println("\nDirectory Listing:");
218+
Serial.println("------------------");
219+
220+
struct fs_dir_t dir;
221+
fs_dir_t_init(&dir);
222+
223+
int ret = fs_opendir(&dir, MOUNT_POINT);
224+
if (ret < 0) {
225+
Serial.print("Failed to open directory (");
226+
Serial.print(ret);
227+
Serial.println(")");
228+
return;
229+
}
230+
231+
struct fs_dirent entry;
232+
int count = 0;
233+
234+
while (true) {
235+
ret = fs_readdir(&dir, &entry);
236+
if (ret < 0) {
237+
Serial.println("Error reading directory");
238+
break;
239+
}
240+
241+
if (entry.name[0] == 0) {
242+
// End of directory
243+
break;
244+
}
245+
246+
Serial.print(" ");
247+
if (entry.type == FS_DIR_ENTRY_DIR) {
248+
Serial.print("[DIR] ");
249+
} else {
250+
Serial.print("[FILE] ");
251+
}
252+
Serial.print(entry.name);
253+
Serial.print(" (");
254+
Serial.print(entry.size);
255+
Serial.println(" bytes)");
256+
257+
count++;
258+
}
259+
260+
fs_closedir(&dir);
261+
262+
if (count == 0) {
263+
Serial.println(" (empty)");
264+
}
265+
266+
Serial.print("\nTotal items: ");
267+
Serial.println(count);
268+
}

0 commit comments

Comments
 (0)