Skip to content

Commit

Permalink
Improve examples
Browse files Browse the repository at this point in the history
  • Loading branch information
carlk3 committed Feb 15, 2023
1 parent e9d34e3 commit 0cf50e3
Show file tree
Hide file tree
Showing 28 changed files with 716 additions and 327 deletions.
1 change: 0 additions & 1 deletion FatFs_SPI

This file was deleted.

31 changes: 20 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,40 +80,49 @@ Directory Listing: 0:/
bf [writable file] [size=4293918720]
```

Results from a port of SdFat's `bench` with a pair of
SanDisk Class 10 A1 16 GB cards:
Results from a port of SdFat's `bench`:

SPI:
```
Card size: 31.95 GB (GB = 1E9 bytes)
...
BUF_SIZE = 20000
FILE_SIZE_MB = 5
BUF_SIZE = 20480
...
write speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
1207.4,22740,14951,16541
1172.1,27632,14960,17047
1384.4,21733,14159,14777
1389.9,18609,14150,14723
...
read speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
1374.4,15424,14150,14554
1374.4,15264,14153,14552
1437.6,15185,14035,14244
1438.4,15008,14046,14238
...
```

SDIO:
```
...
Card size: 31.95 GB (GB = 1E9 bytes)
...
FILE_SIZE_MB = 5
BUF_SIZE = 20480
...
write speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
3690.0,21160,2595,5399
3003.0,22169,3192,6644
6378.2,13172,2588,3194
6488.7,6725,2597,3145
...
read speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
9940.4,2788,1617,2012
9940.4,2614,1617,2010
11915.6,2340,1577,1718
11915.6,2172,1579,1716
...
```

## Choosing the Interface Type(s)
Expand Down
2 changes: 1 addition & 1 deletion examples/PlatformIO/bench2/platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ upload_protocol = picoprobe
monitor_port = COM4
monitor_speed = 115200

build_type = debug
build_type = release

build_flags =
"-Wno-psabi"
Expand Down
166 changes: 88 additions & 78 deletions examples/PlatformIO/data_logger/src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,53 +1,38 @@
/*
/*
Copyright 2023 Carl John Kugler III
Licensed under the Apache License, Version 2.0 (the License); you may not use
this file except in compliance with the License. You may obtain a copy of the
Licensed under the Apache License, Version 2.0 (the License); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
*/

/*
This example reads analog input A0 and logs the voltage
/*
This example reads analog input A0 and logs the voltage
in a file on an SD card once per second.
*/

#include <assert.h>
#include <time.h>
#include "FatFsSd_C.h"

#include "FatFsSd.h"
#include "SerialUART.h"
#include "hardware/adc.h"
#include "hardware/rtc.h"
#include "iostream/ArduinoStream.h"
#include "pico/stdlib.h"

/* Infrastructure*/
#if USE_PRINTF
extern "C" int printf(const char *__restrict format, ...) {
char buf[256] = {0};
va_list xArgs;
va_start(xArgs, format);
vsnprintf(buf, sizeof buf, format, xArgs);
va_end(xArgs);
return Serial1.printf("%s", buf);
}
extern "C" int puts(const char *s) {
return Serial1.println(s);
}
#else
# define printf Serial1.printf
# define puts Serial1.println
#endif
// Serial output stream
ArduinoOutStream cout(Serial1);

/* ********************************************************************** */
/*
This example assumes the following wiring:
| GPIO | Pico Pin | microSD | Function |
| GPIO | Pico Pin | microSD | Function |
| ---- | -------- | ------- | ----------- |
| 16 | 21 | DET | Card Detect |
| 17 | 22 | CLK | SDIO_CLK |
Expand All @@ -62,13 +47,13 @@ This example assumes the following wiring:
// Hardware Configuration of the SD Card "objects"
static sd_card_t sd_cards[] = { // One for each SD card
{
.pcName = "0:", // Name used to mount device
.pcName = "0:", // Name used to mount device
.type = SD_IF_SDIO,
/*
/*
Pins CLK_gpio, D1_gpio, D2_gpio, and D3_gpio are at offsets from pin D0_gpio.
The offsets are determined by sd_driver\SDIO\rp2040_sdio.pio.
CLK_gpio = (D0_gpio + SDIO_CLK_PIN_D0_OFFSET) % 32;
As of this writing, SDIO_CLK_PIN_D0_OFFSET is 30,
As of this writing, SDIO_CLK_PIN_D0_OFFSET is 30,
which is -2 in mod32 arithmetic, so:
CLK_gpio = D0_gpio -2.
D1_gpio = D0_gpio + 1;
Expand All @@ -78,15 +63,14 @@ static sd_card_t sd_cards[] = { // One for each SD card
.sdio_if = {
.CMD_gpio = 18,
.D0_gpio = 19,
.SDIO_PIO = pio1, // Either pio0 or pio1
.DMA_IRQ_num = DMA_IRQ_1 // Either DMA_IRQ_0 or DMA_IRQ_1
.SDIO_PIO = pio1, // Either pio0 or pio1
.DMA_IRQ_num = DMA_IRQ_1 // Either DMA_IRQ_0 or DMA_IRQ_1
},
.use_card_detect = true,
.card_detect_gpio = 16, // Card detect
.card_detected_true = 1 // What the GPIO read returns when a card is
// present.
}
};
.use_card_detect = true,
.card_detect_gpio = 16, // Card detect
.card_detected_true = 1 // What the GPIO read returns when a card is
// present.
}};
extern "C" size_t sd_get_num() { return count_of(sd_cards); }
extern "C" sd_card_t *sd_get_by_num(size_t num) {
if (num <= sd_get_num()) {
Expand All @@ -101,64 +85,88 @@ extern "C" spi_t *spi_get_by_num(size_t num) { return NULL; }

/* ********************************************************************** */

static bool print_header(FIL *fp) {
assert(fp);
FRESULT fr = f_lseek(fp, f_size(fp));
if (FR_OK != fr) {
printf("f_lseek error: %s (%d)\n", FRESULT_str(fr), fr);
return false;
// Check the FRESULT of a library call.
// (See http://elm-chan.org/fsw/ff/doc/rc.html.)
#define FAIL(s, fr) \
{ \
cout << __FILE__ << ":" << __LINE__ << ": " << s << ": " \
<< FRESULT_str(fr) << " (" << fr << ")" << endl; \
for (;;) __breakpoint(); \
}

#define CHK_FRESULT(s, fr) \
{ \
if (FR_OK != fr) \
FAIL(s, fr); \
}
if (0 == f_tell(fp)) {

#define ASSERT(pred) \
{ \
if (!(pred)) { \
cout << __FILE__ << ":" << __LINE__ << ": " \
<< "Assertion failed: " << #pred << endl; \
for (;;) __breakpoint(); \
} \
}

/* ********************************************************************** */

static bool print_heading(FatFs_File &file) {
FRESULT fr = file.lseek(file.size());
CHK_FRESULT("lseek", fr);
if (0 == file.tell()) {
// Print header
if (f_printf(fp, "Date,Time,Temperature (°C)\n") < 0) {
if (file.printf("Date,Time,Voltage\n") < 0) {
printf("f_printf error\n");
return false;
}
}
return true;
}

static bool open_file(FIL *fp) {
assert(fp);
static bool open_file(FatFs_File &file) {
const time_t timer = time(NULL);
struct tm tmbuf;
localtime_r(&timer, &tmbuf);
char filename[64];
int n = snprintf(filename, sizeof filename, "/data");
assert(0 < n && n < (int)sizeof filename);
ASSERT(0 < n && n < (int)sizeof filename);
FRESULT fr = f_mkdir(filename);
if (FR_OK != fr && FR_EXIST != fr) {
printf("f_mkdir error: %s (%d)\n", FRESULT_str(fr), fr);
FAIL("mkdir", fr);
return false;
}
// tm_year int years since 1900
// tm_mon int months since January 0-11
// tm_mday int day of the month 1-31
n += snprintf(filename + n, sizeof filename - n, "/%04d-%02d-%02d",
tmbuf.tm_year + 1900, tmbuf.tm_mon + 1, tmbuf.tm_mday);
assert(0 < n && n < (int)sizeof filename);
ASSERT(0 < n && n < (int)sizeof filename);
fr = f_mkdir(filename);
if (FR_OK != fr && FR_EXIST != fr) {
printf("f_mkdir error: %s (%d)\n", FRESULT_str(fr), fr);
FAIL("mkdir", fr);
return false;
}
size_t nw = strftime(filename + n, sizeof filename - n, "/%H.csv", &tmbuf);
assert(nw);
fr = f_open(fp, filename, FA_OPEN_APPEND | FA_WRITE);
ASSERT(nw);
fr = file.open(filename, FA_OPEN_APPEND | FA_WRITE);
if (FR_OK != fr && FR_EXIST != fr) {
printf("f_open(%s) error: %s (%d)\n", filename, FRESULT_str(fr), fr);
FAIL("open", fr);
return false;
}
if (!print_header(fp)) return false;
if (!print_heading(file)) return false;
return true;
}

bool process_logger() {
/* It's very inefficient to open and close the file for every record,
but you're less likely to lose data that way. But also see f_sync
(http://elm-chan.org/fsw/ff/doc/sync.html). */
FIL fil;
bool rc = open_file(&fil);

FRESULT fr;
FatFs_File file;

bool rc = open_file(file);
if (!rc) return false;

// Form date-time string
Expand All @@ -167,25 +175,27 @@ bool process_logger() {
struct tm tmbuf;
struct tm *ptm = localtime_r(&secs, &tmbuf);
size_t n = strftime(buf, sizeof buf, "%F,%T,", ptm);
assert(n);
ASSERT(n);

/* Assuming something analog is connected to A0 */
int sensorValue = analogRead(A0);
float voltage = 3.3f * sensorValue / 1024;
// printf("Raw value: 0x%03x, voltage: %f V\n", sensorValue, (double)voltage);
int nw = snprintf(buf + n, sizeof buf - n, "%.3f\n", (double)voltage);
assert(0 < nw && nw < (int)sizeof buf);
printf("%s", buf);

if (f_printf(&fil, "%s", buf) < 0) {
printf("f_printf failed\n");
return false;
}
FRESULT fr = f_close(&fil);
if (FR_OK != fr) {
printf("f_close error: %s (%d)\n", FRESULT_str(fr), fr);
return false;
// Notice that only when this returned value is non-negative and less than n,
// the string has been completely written.
ASSERT(0 < nw && nw < (int)sizeof buf);
n += nw;
cout << buf;

UINT bw;
fr = file.write(buf, n, &bw);
CHK_FRESULT("write", fr);
if (bw < n) {
cout << "Short write!" << endl;
for (;;) __breakpoint();
}
fr = file.close();
CHK_FRESULT("close", fr);
return true;
}

Expand All @@ -196,11 +206,11 @@ static absolute_time_t next_log_time;
void setup() {
Serial1.begin(115200); // set up Serial library at 9600 bps
while (!Serial1)
; // Serial is via USB; wait for enumeration
puts("Hello, world!");
; // Serial is via USB; wait for enumeration
cout << "Hello, world!" << endl;

time_init();
// You might want to the user for the time,
// You might want to ask the user for the time,
// but it is hardcoded here for simplicity:
datetime_t t = {
.year = 2023,
Expand All @@ -216,7 +226,7 @@ void setup() {
// http://elm-chan.org/fsw/ff/00index_e.html
sd_card_t *sd_card_p = sd_get_by_num(0);
FRESULT fr = f_mount(&sd_card_p->fatfs, sd_card_p->pcName, 1);
if (FR_OK != fr) panic("f_mount error: %s (%d)\n", FRESULT_str(fr), fr);
CHK_FRESULT("mount", fr);

next_log_time = delayed_by_ms(get_absolute_time(), period);
logger_enabled = true;
Expand Down
1 change: 0 additions & 1 deletion examples/PlatformIO/hw_debug/platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ monitor_speed = 115200
build_flags =
-D USE_PRINTF
-D USE_DBG_PRINTF
-I ../../tests

; Normal way:
; lib_deps =
Expand Down
Loading

0 comments on commit 0cf50e3

Please sign in to comment.