Last active
July 21, 2023 02:06
-
-
Save schollz/67445a165b324d354f432ebab3307a2d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Set minimum required version of CMake | |
cmake_minimum_required(VERSION 3.12) | |
# Include build functions from Pico SDK | |
include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake) | |
# Set name of project (as PROJECT_NAME) and C/C++ standards | |
project(sd_fat_spi C CXX ASM) | |
set(CMAKE_C_STANDARD 11) | |
set(CMAKE_CXX_STANDARD 17) | |
# Creates a pico-sdk subdirectory in our project for the libraries | |
pico_sdk_init() | |
# Tell CMake where to find the executable source file | |
add_executable(${PROJECT_NAME} | |
main.c | |
hw_config.c | |
) | |
# Tell CMake where to find other source code | |
add_subdirectory(lib/no-OS-FatFS-SD-SPI-RPi-Pico/FatFs_SPI build) | |
# Create map/bin/hex/uf2 files | |
pico_add_extra_outputs(${PROJECT_NAME}) | |
# Link to pico_stdlib (gpio, time, etc. functions) | |
target_link_libraries(${PROJECT_NAME} | |
pico_stdlib | |
FatFs_SPI | |
) | |
# Enable usb output, disable uart output | |
pico_enable_stdio_usb(${PROJECT_NAME} 1) | |
pico_enable_stdio_uart(${PROJECT_NAME} 0) | |
pico_add_extra_outputs(${PROJECT_NAME}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* hw_config.c | |
Copyright 2021 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 | |
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 | |
specific language governing permissions and limitations under the License. | |
*/ | |
/* | |
This file should be tailored to match the hardware design. | |
There should be one element of the spi[] array for each hardware SPI used. | |
There should be one element of the sd_cards[] array for each SD card slot. | |
The name is should correspond to the FatFs "logical drive" identifier. | |
(See http://elm-chan.org/fsw/ff/doc/filename.html#vol) | |
The rest of the constants will depend on the type of | |
socket, which SPI it is driven by, and how it is wired. | |
*/ | |
#include <string.h> | |
// | |
#include "my_debug.h" | |
// | |
#include "hw_config.h" | |
// | |
#include "ff.h" /* Obtains integer types */ | |
// | |
#include "diskio.h" /* Declarations of disk functions */ | |
/* | |
This example assumes the following hardware configuration: | |
| | SPI0 | GPIO | Pin | SPI | MicroSD | Description | | ----- | |
| ---- | ----- | --- | -------- | --------- | ---------------------- | | | |
MISO | RX | 16 | 21 | DO | DO | Master In, Slave Out | | |
| MOSI | TX | 19 | 25 | DI | DI | Master Out, Slave In | | |
| SCK | SCK | 18 | 24 | SCLK | CLK | SPI clock | | CS0 | | |
CSn | 17 | 22 | SS or CS | CS | Slave (or Chip) Select | | DET | |
| | 22 | 29 | | CD | Card Detect | | GND | |
| | | 18,23 | | GND | Ground | | 3v3 | |
| | | 36 | | 3v3 | 3.3 volt power | | |
*/ | |
/* | |
This example assumes the following hardware configuration: | |
| | SPI0 | GPIO | Pin | SPI | MicroSD | Description | | ----- | |
| ---- | ----- | --- | -------- | --------- | ---------------------- | | | |
MISO | RX | 12 | 21 | DO | DO | Master In, Slave Out | | |
| MOSI | TX | 15 | 25 | DI | DI | Master Out, Slave In | | |
| SCK | SCK | 14 | 24 | SCLK | CLK | SPI clock | | CS0 | | |
CSn | 13 | 22 | SS or CS | CS | Slave (or Chip) Select | | DET | |
| | 22 | 29 | | CD | Card Detect | | GND | |
| | | 18,23 | | GND | Ground | | 3v3 | |
| | | 36 | | 3v3 | 3.3 volt power | | |
*/ | |
// 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 = 1000 * 1000 | |
// .baud_rate = 12500 * 1000 | |
// .baud_rate = 25 * 1000 * 1000 // Actual frequency: 20833333. | |
}}; | |
// 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 | |
.spi = &spis[0], // Pointer to the SPI driving this card | |
.ss_gpio = 13, // The SPI slave select GPIO for this SD card | |
.use_card_detect = false, | |
.card_detect_gpio = 10, // Card detect | |
.card_detected_true = 0 // What the GPIO read returns when a card is | |
// present. | |
}}; | |
/* ********************************************************************** */ | |
size_t sd_get_num() { return count_of(sd_cards); } | |
sd_card_t *sd_get_by_num(size_t num) { | |
if (num <= sd_get_num()) { | |
return &sd_cards[num]; | |
} else { | |
return NULL; | |
} | |
} | |
size_t spi_get_num() { return count_of(spis); } | |
spi_t *spi_get_by_num(size_t num) { | |
if (num <= spi_get_num()) { | |
return &spis[num]; | |
} else { | |
return NULL; | |
} | |
} | |
/* [] END OF FILE */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <time.h> | |
#include "ff.h" | |
#include "pico/stdlib.h" | |
#include "sd_card.h" | |
clock_t clock() { return (clock_t)time_us_64() / 10000; } | |
void doSomething(int seconds) { sleep_ms(seconds * 1000); } | |
int main() { | |
FRESULT fr; | |
FATFS fs; | |
FIL fil; | |
int ret; | |
char buf[100]; | |
char filename[] = "hello.txt"; | |
char buf2[100]; | |
char filename2[] = "3.raw"; | |
// Initialize chosen serial port | |
stdio_init_all(); | |
// Wait for user to press 'enter' to continue | |
printf("\r\nSD card test. Press 'enter' to start.\r\n"); | |
while (true) { | |
buf[0] = getchar(); | |
if ((buf[0] == '\r') || (buf[0] == '\n')) { | |
break; | |
} | |
} | |
// Initialize SD card | |
if (!sd_init_driver()) { | |
printf("ERROR: Could not initialize SD card\r\n"); | |
while (true) | |
; | |
} | |
// Mount drive | |
fr = f_mount(&fs, "0:", 1); | |
if (fr != FR_OK) { | |
printf("ERROR: Could not mount filesystem (%d)\r\n", fr); | |
while (true) | |
; | |
} | |
FILINFO fno; | |
f_stat(filename, &fno); | |
printf("%s: fsize: %d\n", filename, fno.fsize); | |
// Open file for writing () | |
fr = f_open(&fil, filename, FA_WRITE | FA_CREATE_ALWAYS); | |
if (fr != FR_OK) { | |
printf("ERROR: Could not open file (%d)\r\n", fr); | |
while (true) | |
; | |
} | |
// Write something to file | |
ret = f_printf(&fil, "This is another test\r\n"); | |
if (ret < 0) { | |
printf("ERROR: Could not write to file (%d)\r\n", ret); | |
f_close(&fil); | |
while (true) | |
; | |
} | |
ret = f_printf(&fil, "of writing to an SD card.\r\n"); | |
if (ret < 0) { | |
printf("ERROR: Could not write to file (%d)\r\n", ret); | |
f_close(&fil); | |
while (true) | |
; | |
} | |
// Close file | |
fr = f_close(&fil); | |
if (fr != FR_OK) { | |
printf("ERROR: Could not close file (%d)\r\n", fr); | |
while (true) | |
; | |
} | |
// Open file for reading | |
fr = f_open(&fil, filename, FA_READ); | |
if (fr != FR_OK) { | |
printf("ERROR: Could not open file (%d)\r\n", fr); | |
while (true) | |
; | |
} | |
// Print every line in file over serial | |
printf("Reading from file '%s':\r\n", filename); | |
printf("---\r\n"); | |
while (f_gets(buf, sizeof(buf), &fil)) { | |
printf(buf); | |
} | |
printf("\r\n---\r\n"); | |
printf("\n\nReading from file '%s':\r\n", filename); | |
f_lseek(&fil, 3); | |
while (f_gets(buf, sizeof(buf), &fil)) { | |
printf(buf); | |
} | |
// Close file | |
fr = f_close(&fil); | |
if (fr != FR_OK) { | |
printf("ERROR: Could not close file (%d)\r\n", fr); | |
while (true) | |
; | |
} | |
// read 3.raw | |
f_stat(filename2, &fno); | |
printf("%s: fsize: %d\n", filename2, fno.fsize); | |
// Open file for reading | |
fr = f_open(&fil, filename2, FA_READ); | |
if (fr != FR_OK) { | |
printf("ERROR: Could not open file (%d)\r\n", fr); | |
while (true) | |
; | |
} | |
printf("\n\nReading from file '%s':\r\n", filename2); | |
int16_t count = 0; | |
while (f_gets(buf2, sizeof(buf2), &fil)) { | |
count += 32; | |
} | |
printf("read: %d bytes\n", count); | |
printf("\n\nReading 32 bytes from file '%s':\r\n", filename2); | |
count = 0; | |
f_lseek(&fil, 0); | |
while (f_gets(buf2, sizeof(buf2), &fil)) { | |
for (int8_t i = 0; i < sizeof(buf2); i++) { | |
printf("%x\n", buf2[i]); | |
count++; | |
if (count == 32) { | |
break; | |
} | |
} | |
if (count == 32) { | |
break; | |
} | |
} | |
// Close file | |
fr = f_close(&fil); | |
if (fr != FR_OK) { | |
printf("ERROR: Could not close file (%d)\r\n", fr); | |
while (true) | |
; | |
} | |
// // Unmount drive | |
// f_unmount("0:"); | |
// Loop forever doing nothing | |
while (true) { | |
sleep_ms(1000); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment