diff --git a/FatFs_SPI b/FatFs_SPI deleted file mode 120000 index e831038..0000000 --- a/FatFs_SPI +++ /dev/null @@ -1 +0,0 @@ -src \ No newline at end of file diff --git a/README.md b/README.md index 4c8f4bf..43e7628 100755 --- a/README.md +++ b/README.md @@ -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) diff --git a/examples/PlatformIO/bench2/platformio.ini b/examples/PlatformIO/bench2/platformio.ini index 5c3a84c..a89cee5 100644 --- a/examples/PlatformIO/bench2/platformio.ini +++ b/examples/PlatformIO/bench2/platformio.ini @@ -22,7 +22,7 @@ upload_protocol = picoprobe monitor_port = COM4 monitor_speed = 115200 -build_type = debug +build_type = release build_flags = "-Wno-psabi" diff --git a/examples/PlatformIO/data_logger/src/main.cpp b/examples/PlatformIO/data_logger/src/main.cpp index c6d3ff7..499efd6 100644 --- a/examples/PlatformIO/data_logger/src/main.cpp +++ b/examples/PlatformIO/data_logger/src/main.cpp @@ -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 #include -#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 | @@ -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; @@ -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()) { @@ -101,16 +85,38 @@ 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; } @@ -118,17 +124,16 @@ static bool print_header(FIL *fp) { 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 @@ -136,20 +141,20 @@ static bool open_file(FIL *fp) { // 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; } @@ -157,8 +162,11 @@ 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 @@ -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; } @@ -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, @@ -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; diff --git a/examples/PlatformIO/hw_debug/platformio.ini b/examples/PlatformIO/hw_debug/platformio.ini index bf54a7c..9b754a6 100644 --- a/examples/PlatformIO/hw_debug/platformio.ini +++ b/examples/PlatformIO/hw_debug/platformio.ini @@ -11,7 +11,6 @@ monitor_speed = 115200 build_flags = -D USE_PRINTF -D USE_DBG_PRINTF - -I ../../tests ; Normal way: ; lib_deps = diff --git a/examples/PlatformIO/hw_debug/src/main.cpp b/examples/PlatformIO/hw_debug/src/main.cpp index f5bfc45..0ed4f48 100644 --- a/examples/PlatformIO/hw_debug/src/main.cpp +++ b/examples/PlatformIO/hw_debug/src/main.cpp @@ -1,24 +1,49 @@ -/* -Copyright 2023 Carl John Kugler III +/*----------------------------------------------------------------------/ +/ Low level disk I/O module function checker / +/-----------------------------------------------------------------------/ +/ WARNING: The data on the target drive will be lost! +*/ +/* app4-IO_module_function_checker.c +Originally from [Compatibility Checker for Storage Device Control Module] +(http://elm-chan.org/fsw/ff/res/app4.c). +*/ +/*----------------------------------------------------------------------------/ +/ FatFs - Generic FAT Filesystem Module Rx.xx / +/-----------------------------------------------------------------------------/ +/ +/ Copyright (C) 20xx, ChaN, all right reserved. +/ +/ FatFs module is an open source software. Redistribution and use of FatFs in +/ source and binary forms, with or without modification, are permitted provided +/ that the following condition is met: +/ +/ 1. Redistributions of source code must retain the above copyright notice, +/ this condition and the following disclaimer. +/ +/ This software is provided by the copyright holder and contributors "AS IS" +/ and any warranties related to this software are DISCLAIMED. +/ The copyright owner or contributors be NOT LIABLE for any damages caused +/ by use of this software. +/----------------------------------------------------------------------------*/ +/* +Modifications: 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 runs a low level I/O test than can be helpful for debugging hardware. +/* +This example runs a low level I/O test than can be helpful for debugging hardware. It will destroy the format of the SD card! */ #include "FatFsSd_C.h" -#include "tests/tests.h" -// #include "SerialUART.h" /* Infrastructure*/ @@ -35,50 +60,77 @@ extern "C" int puts(const char *s) { } /* ********************************************************************** */ -/* -This example assumes the following wiring: - - | GPIO | Pico Pin | microSD | Function | - | ---- | -------- | ------- | ----------- | - | 16 | 21 | DET | Card Detect | - | 17 | 22 | CLK | SDIO_CLK | - | 18 | 24 | CMD | SDIO_CMD | - | 19 | 25 | DAT0 | SDIO_D0 | - | 20 | 26 | DAT1 | SDIO_D1 | - | 21 | 27 | DAT2 | SDIO_D2 | - | 22 | 29 | DAT3 | SDIO_D3 | +/* +This example assumes the following wiring for SD card 0: + + | signal | SPI1 | GPIO | card | Description | + | ------ | ---- | ---- | ---- | ---------------------- | + | MISO | RX | 12 | DO | Master In, Slave Out | + | CS0 | CSn | 09 | CS | Slave (or Chip) Select | + | SCK | SCK | 14 | SCLK | SPI clock | + | MOSI | TX | 15 | DI | Master Out, Slave In | + | CD | | 13 | DET | Card Detect | + +This example assumes the following wiring for SD card 1: + + | GPIO | card | Function | + | ---- | ---- | ----------- | + | 16 | DET | Card Detect | + | 17 | CLK | SDIO_CLK | + | 18 | CMD | SDIO_CMD | + | 19 | DAT0 | SDIO_D0 | + | 20 | DAT1 | SDIO_D1 | + | 21 | DAT2 | SDIO_D2 | + | 22 | DAT3 | SDIO_D3 | */ +// Hardware Configuration of SPI "objects" +// Note: multiple SD cards can be driven by one SPI if they use different slave +// selects. +static spi_t spis[] = { // One for each SPI. + { + .hw_inst = spi1, // SPI component + .miso_gpio = 12, // GPIO number (not Pico pin number) + .mosi_gpio = 15, + .sck_gpio = 14, + .baud_rate = 25 * 1000 * 1000, // Actual frequency: 20833333. + .DMA_IRQ_num = DMA_IRQ_0}}; + // 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 + .spi_if = { + .spi = &spis[0], // Pointer to the SPI driving this card + .ss_gpio = 9, // The SPI slave select GPIO for this SD card + }, + .use_card_detect = true, + .card_detect_gpio = 13, // Card detect + .card_detected_true = 1 // What the GPIO read returns when a card is + // present. + }, + { + .pcName = "1:", // 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; D2_gpio = D0_gpio + 2; D3_gpio = D0_gpio + 3; */ - .sdio_if = { - .CMD_gpio = 18, - .D0_gpio = 19, - .SDIO_PIO = pio1, - .DMA_IRQ_num = 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. - } -}; -/* -The following *get_num, *get_by_num functions are required by the library API. + .sdio_if = {.CMD_gpio = 18, .D0_gpio = 19, .SDIO_PIO = pio1, .DMA_IRQ_num = 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. + }}; +/* +The following *get_num, *get_by_num functions are required by the library API. They are how the library finds out about the configuration. */ extern "C" size_t sd_get_num() { return count_of(sd_cards); } @@ -90,15 +142,327 @@ extern "C" sd_card_t *sd_get_by_num(size_t num) { } } // These need to be defined for the API even if SPI is not used: -extern "C" size_t spi_get_num() { return 0; } -extern "C" spi_t *spi_get_by_num(size_t num) { return NULL; } - +extern "C" size_t spi_get_num() { return count_of(spis); } +extern "C" spi_t *spi_get_by_num(size_t num) { + if (num <= spi_get_num()) { + return &spis[num]; + } else { + return NULL; + } +} /* ********************************************************************** */ void setup() { Serial1.begin(115200); // set up Serial library at 9600 bps while (!Serial1) ; // Serial is via USB; wait for enumeration - lliot(0); } -void loop() {} \ No newline at end of file + +static DWORD pn( /* Pseudo random number generator */ + DWORD pns /* !0:Initialize, 0:Read */ +) { + static DWORD lfsr; + UINT n; + + if (pns) { + lfsr = pns; + for (n = 0; n < 32; n++) pn(0); + } + if (lfsr & 1) { + lfsr >>= 1; + lfsr ^= 0x80200003; + } else { + lfsr >>= 1; + } + return lfsr; +} + +static int test_diskio( + BYTE pdrv, /* Physical drive number to be checked (all data on the drive will be lost) */ + UINT ncyc, /* Number of test cycles */ + DWORD *buff, /* Pointer to the working buffer */ + UINT sz_buff /* Size of the working buffer in unit of byte */ +) { + UINT n, cc, ns; + DWORD sz_drv, lba, lba2, sz_eblk, pns = 1; + WORD sz_sect; + BYTE *pbuff = (BYTE *)buff; + DSTATUS ds; + DRESULT dr; + + printf("test_diskio(%u, %u, 0x%08X, 0x%08X)\n", pdrv, ncyc, (UINT)buff, sz_buff); + + if (sz_buff < FF_MAX_SS + 8) { + printf("Insufficient work area to run the program.\n"); + return 1; + } + + for (cc = 1; cc <= ncyc; cc++) { + printf("**** Test cycle %u of %u start ****\n", cc, ncyc); + + printf(" disk_initalize(%u)", pdrv); + ds = disk_initialize(pdrv); + if (ds & STA_NOINIT) { + printf(" - failed.\n"); + return 2; + } else { + printf(" - ok.\n"); + } + + printf("**** Get drive size ****\n"); + printf(" disk_ioctl(%u, GET_SECTOR_COUNT, 0x%08X)", pdrv, (UINT)&sz_drv); + sz_drv = 0; + dr = disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_drv); + if (dr == RES_OK) { + printf(" - ok.\n"); + } else { + printf(" - failed.\n"); + return 3; + } + if (sz_drv < 128) { + printf("Failed: Insufficient drive size to test.\n"); + return 4; + } + printf(" Number of sectors on the drive %u is %lu.\n", pdrv, sz_drv); + +#if FF_MAX_SS != FF_MIN_SS + printf("**** Get sector size ****\n"); + printf(" disk_ioctl(%u, GET_SECTOR_SIZE, 0x%X)", pdrv, (UINT)&sz_sect); + sz_sect = 0; + dr = disk_ioctl(pdrv, GET_SECTOR_SIZE, &sz_sect); + if (dr == RES_OK) { + printf(" - ok.\n"); + } else { + printf(" - failed.\n"); + return 5; + } + printf(" Size of sector is %u bytes.\n", sz_sect); +#else + sz_sect = FF_MAX_SS; +#endif + + printf("**** Get block size ****\n"); + printf(" disk_ioctl(%u, GET_BLOCK_SIZE, 0x%X)", pdrv, (UINT)&sz_eblk); + sz_eblk = 0; + dr = disk_ioctl(pdrv, GET_BLOCK_SIZE, &sz_eblk); + if (dr == RES_OK) { + printf(" - ok.\n"); + } else { + printf(" - failed.\n"); + } + if (dr == RES_OK || sz_eblk >= 2) { + printf(" Size of the erase block is %lu sectors.\n", sz_eblk); + } else { + printf(" Size of the erase block is unknown.\n"); + } + + /* Single sector write test */ + printf("**** Single sector write test ****\n"); + lba = 0; + for (n = 0, pn(pns); n < sz_sect; n++) pbuff[n] = (BYTE)pn(0); + printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba); + dr = disk_write(pdrv, pbuff, lba, 1); + if (dr == RES_OK) { + printf(" - ok.\n"); + } else { + printf(" - failed.\n"); + return 6; + } + printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv); + dr = disk_ioctl(pdrv, CTRL_SYNC, 0); + if (dr == RES_OK) { + printf(" - ok.\n"); + } else { + printf(" - failed.\n"); + return 7; + } + memset(pbuff, 0, sz_sect); + printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba); + dr = disk_read(pdrv, pbuff, lba, 1); + if (dr == RES_OK) { + printf(" - ok.\n"); + } else { + printf(" - failed.\n"); + return 8; + } + for (n = 0, pn(pns); n < sz_sect && pbuff[n] == (BYTE)pn(0); n++) + ; + if (n == sz_sect) { + printf(" Read data matched.\n"); + } else { + printf(" Read data differs from the data written.\n"); + return 10; + } + pns++; + + printf("**** Multiple sector write test ****\n"); + lba = 5; + ns = sz_buff / sz_sect; + if (ns > 4) ns = 4; + if (ns > 1) { + for (n = 0, pn(pns); n < (UINT)(sz_sect * ns); n++) pbuff[n] = (BYTE)pn(0); + printf(" disk_write(%u, 0x%X, %lu, %u)", pdrv, (UINT)pbuff, lba, ns); + dr = disk_write(pdrv, pbuff, lba, ns); + if (dr == RES_OK) { + printf(" - ok.\n"); + } else { + printf(" - failed.\n"); + return 11; + } + printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv); + dr = disk_ioctl(pdrv, CTRL_SYNC, 0); + if (dr == RES_OK) { + printf(" - ok.\n"); + } else { + printf(" - failed.\n"); + return 12; + } + memset(pbuff, 0, sz_sect * ns); + printf(" disk_read(%u, 0x%X, %lu, %u)", pdrv, (UINT)pbuff, lba, ns); + dr = disk_read(pdrv, pbuff, lba, ns); + if (dr == RES_OK) { + printf(" - ok.\n"); + } else { + printf(" - failed.\n"); + return 13; + } + for (n = 0, pn(pns); n < (UINT)(sz_sect * ns) && pbuff[n] == (BYTE)pn(0); n++) + ; + if (n == (UINT)(sz_sect * ns)) { + printf(" Read data matched.\n"); + } else { + printf(" Read data differs from the data written.\n"); + return 14; + } + } else { + printf(" Test skipped.\n"); + } + pns++; + + printf("**** Single sector write test (unaligned buffer address) ****\n"); + lba = 5; + for (n = 0, pn(pns); n < sz_sect; n++) pbuff[n + 3] = (BYTE)pn(0); + printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff + 3), lba); + dr = disk_write(pdrv, pbuff + 3, lba, 1); + if (dr == RES_OK) { + printf(" - ok.\n"); + } else { + printf(" - failed.\n"); + return 15; + } + printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv); + dr = disk_ioctl(pdrv, CTRL_SYNC, 0); + if (dr == RES_OK) { + printf(" - ok.\n"); + } else { + printf(" - failed.\n"); + return 16; + } + memset(pbuff + 5, 0, sz_sect); + printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff + 5), lba); + dr = disk_read(pdrv, pbuff + 5, lba, 1); + if (dr == RES_OK) { + printf(" - ok.\n"); + } else { + printf(" - failed.\n"); + return 17; + } + for (n = 0, pn(pns); n < sz_sect && pbuff[n + 5] == (BYTE)pn(0); n++) + ; + if (n == sz_sect) { + printf(" Read data matched.\n"); + } else { + printf(" Read data differs from the data written.\n"); + return 18; + } + pns++; + + printf("**** 4GB barrier test ****\n"); + if (sz_drv >= 128 + 0x80000000 / (sz_sect / 2)) { + lba = 6; + lba2 = lba + 0x80000000 / (sz_sect / 2); + for (n = 0, pn(pns); n < (UINT)(sz_sect * 2); n++) pbuff[n] = (BYTE)pn(0); + printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba); + dr = disk_write(pdrv, pbuff, lba, 1); + if (dr == RES_OK) { + printf(" - ok.\n"); + } else { + printf(" - failed.\n"); + return 19; + } + printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff + sz_sect), lba2); + dr = disk_write(pdrv, pbuff + sz_sect, lba2, 1); + if (dr == RES_OK) { + printf(" - ok.\n"); + } else { + printf(" - failed.\n"); + return 20; + } + printf(" disk_ioctl(%u, CTRL_SYNC, NULL)", pdrv); + dr = disk_ioctl(pdrv, CTRL_SYNC, 0); + if (dr == RES_OK) { + printf(" - ok.\n"); + } else { + printf(" - failed.\n"); + return 21; + } + memset(pbuff, 0, sz_sect * 2); + printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)pbuff, lba); + dr = disk_read(pdrv, pbuff, lba, 1); + if (dr == RES_OK) { + printf(" - ok.\n"); + } else { + printf(" - failed.\n"); + return 22; + } + printf(" disk_read(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff + sz_sect), lba2); + dr = disk_read(pdrv, pbuff + sz_sect, lba2, 1); + if (dr == RES_OK) { + printf(" - ok.\n"); + } else { + printf(" - failed.\n"); + return 23; + } + for (n = 0, pn(pns); pbuff[n] == (BYTE)pn(0) && n < (UINT)(sz_sect * 2); n++) + ; + if (n == (UINT)(sz_sect * 2)) { + printf(" Read data matched.\n"); + } else { + printf(" Read data differs from the data written.\n"); + return 24; + } + } else { + printf(" Test skipped.\n"); + } + pns++; + + printf("**** Test cycle %u of %u completed ****\n\n", cc, ncyc); + } + + return 0; +} + +// int main (int argc, char* argv[]) +int lliot(size_t pnum) { + int rc; + DWORD buff[FF_MAX_SS]; /* Working buffer (4 sector in size) */ + + /* Check function/compatibility of the physical drive #0 */ + rc = test_diskio(pnum, 3, buff, sizeof buff); + + if (rc) { + printf("Sorry the function/compatibility test failed. (rc=%d)\nFatFs will not work with this disk driver.\n", rc); + } else { + printf("Congratulations! The disk driver works well.\n"); + } + + return rc; +} + +void loop() { + for (size_t i = 0; i < sd_get_num(); ++i) { + printf("\nTesting drive &lu\n", i); + lliot(i); + sleep_ms(10000); + } +} \ No newline at end of file diff --git a/examples/PlatformIO/one_SDIO/src/main.cpp b/examples/PlatformIO/one_SDIO/src/main.cpp index d0c3d7d..6b5ca08 100644 --- a/examples/PlatformIO/one_SDIO/src/main.cpp +++ b/examples/PlatformIO/one_SDIO/src/main.cpp @@ -13,6 +13,7 @@ specific language governing permissions and limitations under the License. */ /* Write "Hello, world!\n" to SD Card */ +#include #include "FatFsSd_C.h" // #include "SerialUART.h" @@ -78,6 +79,15 @@ extern "C" spi_t *spi_get_by_num(size_t num) { return NULL; } /* ********************************************************************** */ +// Check the FRESULT of a library call. +// (See http://elm-chan.org/fsw/ff/doc/rc.html.) +#define CHK_FRESULT(s, fr) \ + if (FR_OK != fr) { \ + printf("%s:%d %s error: %s (%d)\n", \ + __FILE__, __LINE__, s, FRESULT_str(fr), fr); \ + for (;;) __breakpoint(); \ + } + void setup() { Serial1.begin(115200); // set up Serial library at 9600 bps while (!Serial1) @@ -89,27 +99,20 @@ void setup() { // http://elm-chan.org/fsw/ff/00index_e.html sd_card_t *pSD = sd_get_by_num(0); FRESULT fr = f_mount(&pSD->fatfs, pSD->pcName, 1); - if (FR_OK != fr) { - printf("f_mount error: %s (%d)\n", FRESULT_str(fr), fr); - for (;;) __BKPT(1); - } + CHK_FRESULT("f_mount", fr); FIL fil; const char* const filename = "filename.txt"; fr = f_open(&fil, 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); - for (;;) __BKPT(2); - } - if (f_printf(&fil, "Hello, world!\n") < 0) { + CHK_FRESULT("f_open", fr); + char const * const str = "Hello, world!\n"; + if (f_printf(&fil, str) < strlen(str)) { printf("f_printf failed\n"); - for (;;) __BKPT(3); + for (;;) __breakpoint(); } fr = f_close(&fil); - if (FR_OK != fr) { - printf("f_close error: %s (%d)\n", FRESULT_str(fr), fr); - for (;;) __BKPT(4); - } - f_unmount(pSD->pcName); + CHK_FRESULT("f_close", fr); + fr = f_unmount(pSD->pcName); + CHK_FRESULT("f_unmount", fr); puts("Goodbye, world!"); } diff --git a/examples/PlatformIO/one_SPI.C++/src/main.cpp b/examples/PlatformIO/one_SPI.C++/src/main.cpp index 7263c79..43d4497 100644 --- a/examples/PlatformIO/one_SPI.C++/src/main.cpp +++ b/examples/PlatformIO/one_SPI.C++/src/main.cpp @@ -23,20 +23,16 @@ ArduinoOutStream cout(Serial1); /* ********************************************************************** */ -// First (if s is not NULL and *s is not a null byte ('\0')) the argument string s is printed, -// followed by a colon and a blank. Then the FRESULT error message and a new-line. -static void chk_result(const char* s, FRESULT fr) { - if (FR_OK != fr) { - if (s && *s) - cout << __LINE__ << ": " << s << ": " << FRESULT_str(fr) << " (" << fr << ")" << endl; - else - cout << __LINE__ << ": " << FRESULT_str(fr) << " (" << fr << ")" << endl; - for (;;) __breakpoint(); +// Check the FRESULT of a library call. +// (See http://elm-chan.org/fsw/ff/doc/rc.html.) +#define CHK_RESULT(s, fr) \ + if (FR_OK != fr) { \ + cout << __FILE__ << ":" << __LINE__ << ": " << s << ": " \ + << FRESULT_str(fr) << " (" << fr << ")" << endl; \ + for (;;) __breakpoint(); \ } -} void setup() { - Serial1.begin(115200); // set up Serial library while (!Serial1) ; // Serial is via USB; wait for enumeration @@ -80,28 +76,29 @@ void setup() { 13, // uint card_detect_gpio = 0, // Card detect; ignored if !use_card_detect 1 // uint card_detected_true = false // Varies with card socket; ignored if !use_card_detect ); - + FatFs_SdCard& card(FatFs::add_sd_card_p(spi_sd_card)); -/* ********************************************************************** */ + /* ********************************************************************** */ cout << "\033[2J\033[H"; // Clear Screen cout << "Hello, world!" << endl; // sd_card_t* pSD = sd_get_by_num(0); - FRESULT fr =card.mount(); - chk_result("mount", fr); + FRESULT fr = card.mount(); + CHK_RESULT("mount", fr); FatFs_File file; char const* const filename = "filename.txt"; fr = file.open(filename, FA_OPEN_APPEND | FA_WRITE); - chk_result("open", fr); + CHK_RESULT("open", fr); char const* const str = "Hello, world!\n"; if (file.printf(str) < strlen(str)) { - cout << "printf failed\n" << endl; + cout << "printf failed\n" + << endl; for (;;) __breakpoint(); } fr = file.close(); - chk_result("close", fr); + CHK_RESULT("close", fr); fr = card.unmount(); - chk_result("unmount", fr); + CHK_RESULT("unmount", fr); cout << "Goodbye, world!" << endl; } diff --git a/examples/PlatformIO/one_SPI_one_SDIO.C++/platformio.ini b/examples/PlatformIO/one_SPI_one_SDIO.C++/platformio.ini index 5e0e1df..dc5a31a 100644 --- a/examples/PlatformIO/one_SPI_one_SDIO.C++/platformio.ini +++ b/examples/PlatformIO/one_SPI_one_SDIO.C++/platformio.ini @@ -12,8 +12,8 @@ monitor_speed = 115200 ; build_flags = -fexceptions build_flags = "-Wno-psabi" - "-D USE_PRINTF" - "-D USE_DBG_PRINTF" + ; "-D USE_PRINTF" + ; "-D USE_DBG_PRINTF" ; Normal way: ; lib_deps = diff --git a/examples/PlatformIO/one_SPI_one_SDIO.C++/src/main.cpp b/examples/PlatformIO/one_SPI_one_SDIO.C++/src/main.cpp index 6293de5..99b0ddb 100644 --- a/examples/PlatformIO/one_SPI_one_SDIO.C++/src/main.cpp +++ b/examples/PlatformIO/one_SPI_one_SDIO.C++/src/main.cpp @@ -12,130 +12,14 @@ CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ +#include + #include "FatFsSd.h" #include "SerialUART.h" +#include "iostream/ArduinoStream.h" -/* Infrastructure*/ -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); -} - -/* ********************************************************************** */ - -// First (if s is not NULL and *s is not a null byte ('\0')) the argument string s is printed, -// followed by a colon and a blank. Then the FRESULT error message and a new-line. -static void chk_result(const char *s, FRESULT fr) { - if (FR_OK != fr) { - if (s && *s) - printf("%s: %s (%d)\n", s, FRESULT_str(fr), fr); - else - printf("%s (%d)\n", FRESULT_str(fr), fr); - for (;;) __breakpoint(); - } -} - -void ls(const char *dir) { - char cwdbuf[FF_LFN_BUF] = {0}; - FRESULT fr; /* Return value */ - char const *dir_str; - if (dir[0]) { - dir_str = dir; - } else { - fr = FatFs_Dir::getcwd(cwdbuf, sizeof cwdbuf); - chk_result("getcwd", fr); - dir_str = cwdbuf; - } - printf("Directory Listing: %s\n", dir_str); - FILINFO fno; /* File information */ - memset(&fno, 0, sizeof fno); - FatFs_Dir dirobj; - fr = dirobj.findfirst(&fno, dir_str, "*"); - chk_result("findfirst", fr); - while (fr == FR_OK && fno.fname[0]) { /* Repeat while an item is found */ - /* Create a string that includes the file name, the file size and the - attributes string. */ - const char *pcWritableFile = "writable file", - *pcReadOnlyFile = "read only file", - *pcDirectory = "directory"; - const char *pcAttrib; - /* Point pcAttrib to a string that describes the file. */ - if (fno.fattrib & AM_DIR) { - pcAttrib = pcDirectory; - } else if (fno.fattrib & AM_RDO) { - pcAttrib = pcReadOnlyFile; - } else { - pcAttrib = pcWritableFile; - } - /* Create a string that includes the file name, the file size and the - attributes string. */ - printf("%s [%s] [size=%llu]\n", fno.fname, pcAttrib, fno.fsize); - - fr = dirobj.findnext(&fno); /* Search for next item */ - } - dirobj.closedir(); -} - -static void test(FatFs_SdCard *FatFs_SdCard_p) { - FRESULT fr; - - printf("Testing drive %s\n", FatFs_SdCard_p->get_name()); - - fr = FatFs_SdCard_p->mount(); - chk_result("mount", fr); - fr = FatFs::chdrive(FatFs_SdCard_p->get_name()); - chk_result("chdrive", fr); - ls(NULL); - - FatFs_File file; - fr = file.open("filename.txt", FA_OPEN_APPEND | FA_WRITE); - chk_result("open", fr); - - if (file.printf("Hello, world!\n") < 0) { - printf("f_printf failed\n"); - for (;;) __breakpoint(); - } - fr = file.close(); - chk_result("close", fr); - - ls(NULL); - - fr = FatFs_Dir::mkdir("subdir"); - if (FR_OK != fr && FR_EXIST != fr) { - printf("f_mkdir error: %s (%d)\n", FRESULT_str(fr), fr); - for (;;) __breakpoint(); - } - fr = FatFs_Dir::chdir("subdir"); - chk_result("chdir", fr); - fr = file.open("filename2.txt", FA_OPEN_APPEND | FA_WRITE); - chk_result("open", fr); - char const str[] = "Hello again\n"; - UINT bw; - fr = file.write(str, strlen(str) + 1, &bw); - chk_result("write", fr); - if (strlen(str) + 1 != bw) { - printf("Short write!\n"); - for (;;) __breakpoint(); - } - fr = file.close(); - chk_result("close", fr); - - ls(NULL); - - fr = FatFs_Dir::chdir("/"); - chk_result("chdir", fr); - - ls(NULL); - - FatFs_SdCard_p->unmount(); -} +// Serial output stream +ArduinoOutStream cout(Serial1); /* ********************************************************************** */ /* @@ -176,8 +60,8 @@ void setup() { Serial1.begin(115200); // set up Serial library at 9600 bps while (!Serial1) ; // Serial is via USB; wait for enumeration - printf("\033[2J\033[H"); // Clear Screen - puts("Hello, world!"); + cout << "\033[2J\033[H"; // Clear Screen + cout << "Hello, world!" << endl; /* Hardware Configuration of SPI object */ @@ -216,8 +100,122 @@ void setup() { ); FatFs::add_sd_card_p(sdio_sd_card); } + +/* ********************************************************************** */ + +// Check the FRESULT of a library call. +// (See http://elm-chan.org/fsw/ff/doc/rc.html.) +#define CHK_FRESULT(s, fr) \ + if (FR_OK != fr) { \ + cout << __FILE__ << ":" << __LINE__ << ": " << s << ": " \ + << FRESULT_str(fr) << " (" << fr << ")" << endl; \ + for (;;) __breakpoint(); \ + } + +void ls(const char *dir) { + char cwdbuf[FF_LFN_BUF] = {0}; + FRESULT fr; /* Return value */ + char const *dir_str; + if (dir[0]) { + dir_str = dir; + } else { + fr = FatFs_Dir::getcwd(cwdbuf, sizeof cwdbuf); + CHK_FRESULT("getcwd", fr); + dir_str = cwdbuf; + } + cout << "Directory Listing: " << dir_str << endl; + FILINFO fno = {}; /* File information */ + FatFs_Dir dirobj; + fr = dirobj.findfirst(&fno, dir_str, "*"); + CHK_FRESULT("findfirst", fr); + while (fr == FR_OK && fno.fname[0]) { /* Repeat while an item is found */ + /* Create a string that includes the file name, the file size and the + attributes string. */ + const char *pcWritableFile = "writable file", + *pcReadOnlyFile = "read only file", + *pcDirectory = "directory"; + const char *pcAttrib; + /* Point pcAttrib to a string that describes the file. */ + if (fno.fattrib & AM_DIR) { + pcAttrib = pcDirectory; + } else if (fno.fattrib & AM_RDO) { + pcAttrib = pcReadOnlyFile; + } else { + pcAttrib = pcWritableFile; + } + /* Create a string that includes the file name, the file size and the + attributes string. */ + cout << fno.fname << " [" << pcAttrib << "]" + << "[size=" << fno.fsize << "]" << endl; + + fr = dirobj.findnext(&fno); /* Search for next item */ + } + dirobj.closedir(); +} + +static void test(FatFs_SdCard *FatFs_SdCard_p) { + FRESULT fr; + + cout << endl << "Testing drive " << FatFs_SdCard_p->get_name() << endl; + + fr = FatFs_SdCard_p->mount(); + CHK_FRESULT("mount", fr); + fr = FatFs::chdrive(FatFs_SdCard_p->get_name()); + CHK_FRESULT("chdrive", fr); + ls(NULL); + + FatFs_File file; + fr = file.open("filename.txt", FA_OPEN_APPEND | FA_WRITE); + CHK_FRESULT("open", fr); + { + char const *const str = "Hello, world!\n"; + if (file.printf(str) < strlen(str)) { + cout << "printf failed" << endl; + ; + for (;;) __breakpoint(); + } + } + fr = file.close(); + CHK_FRESULT("close", fr); + + ls("/"); + + fr = FatFs_Dir::mkdir("subdir"); + if (FR_OK != fr && FR_EXIST != fr) { + cout << "mkdir error: " << FRESULT_str(fr) << "(" << fr << ")" << endl; + for (;;) __breakpoint(); + } + fr = FatFs_Dir::chdir("subdir"); + CHK_FRESULT("chdir", fr); + fr = file.open("filename2.txt", FA_OPEN_APPEND | FA_WRITE); + CHK_FRESULT("open", fr); + { + char const *const str = "Hello again\n"; + UINT bw; + fr = file.write(str, strlen(str) + 1, &bw); + CHK_FRESULT("write", fr); + if (strlen(str) + 1 != bw) { + cout << "Short write!" << endl; + ; + for (;;) __breakpoint(); + } + } + fr = file.close(); + CHK_FRESULT("close", fr); + + ls(NULL); + + fr = FatFs_Dir::chdir("/"); + CHK_FRESULT("chdir", fr); + + ls(NULL); + + fr = FatFs_SdCard_p->unmount(); + CHK_FRESULT("unmount", fr); +} + void loop() { for (size_t i = 0; i < FatFs::SdCard_get_num(); ++i) test(FatFs::SdCard_get_by_num(i)); - sleep_ms(500); + sleep_ms(1000); } \ No newline at end of file diff --git a/examples/command_line/CMakeLists.txt b/examples/command_line/CMakeLists.txt index 1bdbfb0..bd900f3 100644 --- a/examples/command_line/CMakeLists.txt +++ b/examples/command_line/CMakeLists.txt @@ -8,7 +8,7 @@ project(command_line C CXX ASM) set(CMAKE_C_STANDARD 11) set(CMAKE_CXX_STANDARD 17) -add_compile_options(-Os) # Optimize for size (place before pico_sdk_init) +# add_compile_options(-Os) # Optimize for size (place before pico_sdk_init) # Initialise the Pico SDK pico_sdk_init() @@ -20,12 +20,12 @@ add_executable(command_line main.cpp hw_config.c data_log_demo.c - ../../src/tests/bench.c - ../../src/tests/simple.c - ../../src/tests/app4-IO_module_function_checker.c - ../../src/tests/big_file_test.c - ../../src/tests/CreateAndVerifyExampleFiles.c - ../../src/tests/ff_stdio_tests_with_cwd.c + tests/bench.c + tests/simple.c + tests/app4-IO_module_function_checker.c + tests/big_file_test.c + tests/CreateAndVerifyExampleFiles.c + tests/ff_stdio_tests_with_cwd.c ) # Add the standard library to the build target_link_libraries(command_line pico_stdlib) diff --git a/examples/command_line/main.cpp b/examples/command_line/main.cpp index b1e8f2c..9f243b0 100644 --- a/examples/command_line/main.cpp +++ b/examples/command_line/main.cpp @@ -18,7 +18,7 @@ #include "my_debug.h" #include "rtc.h" #include "sd_card.h" -#include "tests.h" +#include "tests/tests.h" // #include "util.h" // for wiring test #ifndef USE_PRINTF diff --git a/src/tests/CreateAndVerifyExampleFiles.c b/examples/command_line/tests/CreateAndVerifyExampleFiles.c similarity index 100% rename from src/tests/CreateAndVerifyExampleFiles.c rename to examples/command_line/tests/CreateAndVerifyExampleFiles.c diff --git a/src/tests/app4-IO_module_function_checker.c b/examples/command_line/tests/app4-IO_module_function_checker.c similarity index 100% rename from src/tests/app4-IO_module_function_checker.c rename to examples/command_line/tests/app4-IO_module_function_checker.c diff --git a/src/tests/bench.c b/examples/command_line/tests/bench.c similarity index 100% rename from src/tests/bench.c rename to examples/command_line/tests/bench.c diff --git a/src/tests/big_file_test.c b/examples/command_line/tests/big_file_test.c similarity index 100% rename from src/tests/big_file_test.c rename to examples/command_line/tests/big_file_test.c diff --git a/src/tests/ff_stdio_tests_with_cwd.c b/examples/command_line/tests/ff_stdio_tests_with_cwd.c similarity index 100% rename from src/tests/ff_stdio_tests_with_cwd.c rename to examples/command_line/tests/ff_stdio_tests_with_cwd.c diff --git a/src/tests/simple.c b/examples/command_line/tests/simple.c similarity index 100% rename from src/tests/simple.c rename to examples/command_line/tests/simple.c diff --git a/src/tests/tests.h b/examples/command_line/tests/tests.h similarity index 100% rename from src/tests/tests.h rename to examples/command_line/tests/tests.h diff --git a/include/FatFsSd.h b/include/FatFsSd.h index 191e954..2e54562 100644 --- a/include/FatFsSd.h +++ b/include/FatFsSd.h @@ -57,8 +57,11 @@ class FatFs_Spi { class FatFs_SdCard { protected: sd_card_t m_sd_card = {}; + FatFs_SdCard() {} public: + FatFs_SdCard(sd_card_t sd_card): m_sd_card(sd_card) {} + const char* get_name() { return m_sd_card.pcName; } FRESULT mount() { diff --git a/library.json b/library.json index 15c56eb..6ca8d45 100755 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "no-OS-FatFS-SD-SPI-RPi-Pico", - "version": "1.0.3", + "version": "1.0.5", "description": "Simple library for SD Cards on the RP2040", "keywords": ["Data Storage", "FatFs", "SD card", "Secure Digital card", "SPI", "SDIO"], "repository": @@ -65,30 +65,29 @@ "files": [ "platformio.ini", "src/main.cpp", - "src/tests/app4-IO_module_function_checker.c" + "../../../src/tests/app4-IO_module_function_checker.c" ] } ], "build": { "srcFilter": [ "-<.git/> -<.svn/>", - "+", "+", "+", "+", - "+", - "+", - "+", - "+", - "+", + "+", "+", "+", - "+", "+", "+", "+", "+", - "+" + "+", + "+", + "+", + "+", + "+", + "+" ], "flags": [ "-I include", diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 53be16e..34edf4a 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -17,11 +17,11 @@ target_sources(FatFs_SPI INTERFACE ${CMAKE_CURRENT_LIST_DIR}/sd_driver/SPI/sd_spi.c ${CMAKE_CURRENT_LIST_DIR}/sd_driver/SPI/sd_card_spi.c ${CMAKE_CURRENT_LIST_DIR}/sd_driver/SPI/spi.c - ${CMAKE_CURRENT_LIST_DIR}/f_util.c - ${CMAKE_CURRENT_LIST_DIR}/ff_stdio.c - ${CMAKE_CURRENT_LIST_DIR}/glue.c - ${CMAKE_CURRENT_LIST_DIR}/my_debug.c - ${CMAKE_CURRENT_LIST_DIR}/rtc.c + ${CMAKE_CURRENT_LIST_DIR}/source/f_util.c + ${CMAKE_CURRENT_LIST_DIR}/source/ff_stdio.c + ${CMAKE_CURRENT_LIST_DIR}/source/glue.c + ${CMAKE_CURRENT_LIST_DIR}/source/my_debug.c + ${CMAKE_CURRENT_LIST_DIR}/source/rtc.c ) target_include_directories(FatFs_SPI INTERFACE ff15/source diff --git a/src/FatFsSd.cpp b/src/source/FatFsSd.cpp similarity index 84% rename from src/FatFsSd.cpp rename to src/source/FatFsSd.cpp index f7bfe26..313f68f 100644 --- a/src/FatFsSd.cpp +++ b/src/source/FatFsSd.cpp @@ -12,12 +12,12 @@ CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ +#include "FatFsSd.h" + #include #include #include -#include "FatFsSd.h" - /* See FatFs - Generic FAT Filesystem Module, "Application Interface", http://elm-chan.org/fsw/ff/00index_e.html @@ -26,10 +26,18 @@ specific language governing permissions and limitations under the License. std::vector FatFs::Spis; std::vector FatFs::SdCards; -size_t spi_get_num() { return FatFs::Spi_get_num(); } -spi_t *spi_get_by_num(size_t num) { return &FatFs::Spi_get_by_num(num)->m_spi; } -size_t sd_get_num() { return FatFs::SdCard_get_num(); } -sd_card_t *sd_get_by_num(size_t num) { return &FatFs::SdCard_get_by_num(num)->m_sd_card; } +size_t __attribute__((weak)) spi_get_num() { + return FatFs::Spi_get_num(); +} +spi_t __attribute__((weak)) *spi_get_by_num(size_t num) { + return &FatFs::Spi_get_by_num(num)->m_spi; +} +size_t __attribute__((weak)) sd_get_num() { + return FatFs::SdCard_get_num(); +} +sd_card_t __attribute__((weak)) *sd_get_by_num(size_t num) { + return &FatFs::SdCard_get_by_num(num)->m_sd_card; +} /* Put a formatted string to the file */ int FatFs_File::printf(const TCHAR *format, ...) { diff --git a/src/f_util.c b/src/source/f_util.c similarity index 100% rename from src/f_util.c rename to src/source/f_util.c diff --git a/src/ff_stdio.c b/src/source/ff_stdio.c similarity index 100% rename from src/ff_stdio.c rename to src/source/ff_stdio.c diff --git a/src/glue.c b/src/source/glue.c similarity index 100% rename from src/glue.c rename to src/source/glue.c diff --git a/src/my_debug.c b/src/source/my_debug.c similarity index 100% rename from src/my_debug.c rename to src/source/my_debug.c diff --git a/src/rtc.c b/src/source/rtc.c similarity index 100% rename from src/rtc.c rename to src/source/rtc.c