├── .gitignore ├── AUTHORS ├── CMakeLists.txt ├── LICENSE ├── README.md ├── linux ├── Image ├── Makefile ├── c4 │ └── Makefile └── configs │ ├── buildroot_config │ ├── busybox_config │ ├── custom_kernel_config │ └── rootfsoverlay │ └── etc │ └── inittab ├── no-OS-FatFS-SD-SPI-RPi-Pico ├── .gitignore ├── LICENSE ├── README.md ├── examples │ ├── PlatformIO │ │ ├── bench2 │ │ │ ├── .gitignore │ │ │ ├── include │ │ │ │ └── README │ │ │ ├── lib │ │ │ │ └── README │ │ │ ├── platformio.ini │ │ │ ├── src │ │ │ │ └── main.cpp │ │ │ └── test │ │ │ │ └── README │ │ ├── data_logger │ │ │ ├── .gitignore │ │ │ ├── platformio.ini │ │ │ └── src │ │ │ │ └── main.cpp │ │ ├── hw_debug │ │ │ ├── .gitignore │ │ │ ├── platformio.ini │ │ │ └── src │ │ │ │ └── main.cpp │ │ ├── one_SDIO │ │ │ ├── .gitignore │ │ │ ├── platformio.ini │ │ │ └── src │ │ │ │ └── main.cpp │ │ ├── one_SPI.C++ │ │ │ ├── .gitignore │ │ │ ├── platformio.ini │ │ │ └── src │ │ │ │ └── main.cpp │ │ ├── one_SPI │ │ │ ├── .gitignore │ │ │ ├── platformio.ini │ │ │ └── src │ │ │ │ └── main.cpp │ │ ├── one_SPI_one_SDIO.C++ │ │ │ ├── .gitignore │ │ │ ├── platformio.ini │ │ │ └── src │ │ │ │ └── main.cpp │ │ └── one_SPI_one_SDIO │ │ │ ├── .gitignore │ │ │ ├── platformio.ini │ │ │ └── src │ │ │ └── main.cpp │ ├── command_line │ │ ├── CMakeLists.txt │ │ ├── data_log_demo.c │ │ ├── hw_config.c │ │ ├── main.cpp │ │ ├── maker_pi_pico.hw_config.c │ │ ├── pico_sdk_import.cmake │ │ ├── tests │ │ │ ├── CreateAndVerifyExampleFiles.c │ │ │ ├── app4-IO_module_function_checker.c │ │ │ ├── bench.c │ │ │ ├── big_file_test.c │ │ │ ├── ff_stdio_tests_with_cwd.c │ │ │ ├── simple.c │ │ │ └── tests.h │ │ └── thing_plus.hw_config.c │ ├── dynamic_config │ │ ├── CMakeLists.txt │ │ ├── main.cpp │ │ └── pico_sdk_import.cmake │ └── simple │ │ ├── CMakeLists.txt │ │ ├── hw_config.c │ │ ├── main.c │ │ ├── pico_sdk_import.cmake │ │ └── thing_plus.hw_config.c ├── include │ ├── FatFsSd.h │ ├── FatFsSd_C.h │ └── iostream │ │ ├── ArduinoStream.h │ │ ├── StdioStream.cpp │ │ ├── StdioStream.h │ │ ├── StreamBaseClass.cpp │ │ ├── bufstream.h │ │ ├── fstream.h │ │ ├── ios.h │ │ ├── iostream.h │ │ ├── istream.cpp │ │ ├── istream.h │ │ ├── ostream.cpp │ │ └── ostream.h ├── library.json └── src │ ├── CMakeLists.txt │ ├── SdFat │ ├── LICENSE.md │ └── README.md │ ├── ZuluSCSI-firmware │ ├── LICENSE │ └── README.md │ ├── ff15 │ ├── LICENSE.txt │ ├── documents │ │ ├── css_e.css │ │ └── res │ │ │ ├── app1.c │ │ │ ├── app2.c │ │ │ ├── app3.c │ │ │ ├── app4.c │ │ │ ├── app5.c │ │ │ └── app6.c │ └── source │ │ ├── 00history.txt │ │ ├── 00readme.txt │ │ ├── diskio.c │ │ ├── diskio.h │ │ ├── ff.c │ │ ├── ff.h │ │ ├── ffconf.h │ │ ├── ffsystem.c │ │ └── ffunicode.c │ ├── include │ ├── f_util.h │ ├── ff_stdio.h │ ├── ffconf.h │ ├── my_debug.h │ ├── rtc.h │ └── util.h │ ├── mbed-os │ ├── LICENSE-apache-2.0.txt │ ├── LICENSE.md │ └── README.md │ ├── sd_driver │ ├── SDIO │ │ ├── SdioCard.h │ │ ├── ZuluSCSI_platform.h │ │ ├── rp2040_sdio.c │ │ ├── rp2040_sdio.h │ │ ├── rp2040_sdio.pio │ │ ├── rp2040_sdio.pio.h │ │ └── sd_card_sdio.c │ ├── SPI │ │ ├── crc.c │ │ ├── crc.h │ │ ├── sd_card_constants.h │ │ ├── sd_card_spi.c │ │ ├── sd_card_spi.h │ │ ├── sd_spi.c │ │ ├── sd_spi.h │ │ ├── spi.c │ │ └── spi.h │ ├── SdCardInfo.h │ ├── hw_config.h │ ├── sd_card.c │ └── sd_card.h │ └── source │ ├── FatFsSd.cpp │ ├── f_util.c │ ├── ff_stdio.c │ ├── glue.c │ ├── my_debug.c │ └── rtc.c ├── pico-displayDrivs ├── CMakeLists.txt ├── README.md ├── gfx │ ├── CMakeLists.txt │ ├── font.h │ ├── gfx.c │ ├── gfx.h │ └── gfxfont.h └── st7735 │ ├── CMakeLists.txt │ ├── README.md │ ├── st7735.c │ └── st7735.h ├── pico-ps2Driv ├── CMakeLists.txt ├── README.md ├── ps2.c └── ps2.h ├── pico-rv32ima ├── CMakeLists.txt ├── cache │ ├── cache.c │ └── cache.h ├── config │ ├── rv32_config.h │ └── sd_hw_config.c ├── console │ ├── console.c │ ├── console.h │ ├── terminal.c │ ├── terminal.h │ ├── tusb_inc │ │ └── tusb_config.h │ └── usb_descriptors.c ├── emulator │ ├── default64mbdtc.h │ ├── emulator.c │ ├── emulator.h │ └── mini-rv32ima.h ├── main.c └── psram │ ├── psram.c │ └── psram.h ├── pico_sdk_import.cmake └── pictures ├── lcd.jpg └── screenshot.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | #ignore build folder 2 | build/ 3 | 4 | #ignore .vscode 5 | .vscode/ 6 | 7 | #ignore buildroot folder 8 | linux/buildroot 9 | 10 | #ignore c4 source folder 11 | linux/c4/c4src 12 | 13 | # Incase i forget to remove 14 | linux/output 15 | 16 | # Don't add build 17 | build_debug/ -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | File/folder Authors 2 | 3 | no-OS-FatFS-SD-SPI-RPi-Pico -> tvlad1234, carlk3 4 | pico-displayDrivs -> tvlad1234, ElectroBoy404NotFound 5 | pico-ps2Driv -> tvlad1234 6 | 7 | pico-rv32ima/cache -> xhackerustc, tvlad1234, ElectroBoy404NotFound 8 | pico-rv32ima/psram -> tvlad1234, ElectroBoy404NotFound 9 | pico-rv32ima/emulator -> cnlohr, tvlad1234, ElectroBoy404NotFound 10 | pico-rv32ima/config -> tvlad1234, ElectroBoy404NotFound 11 | pico-rv32ima/console -> tvlad1234, ElectroBoy404NotFound 12 | pico-rv32ima/main.c -> tvlad1234, ElectroBoy404NotFound 13 | 14 | linux -> tvlad1234 15 | pictures -> tvlad1234 -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | # Pull in SDK (must be before project) 4 | include(pico_sdk_import.cmake) 5 | 6 | project(picorv C CXX ASM) 7 | set(CMAKE_C_STANDARD 11) 8 | set(CMAKE_CXX_STANDARD 17) 9 | 10 | # Initialize the SDK 11 | pico_sdk_init() 12 | 13 | add_subdirectory(no-OS-FatFS-SD-SPI-RPi-Pico/src) 14 | add_subdirectory(pico-displayDrivs) 15 | add_subdirectory(pico-ps2Driv) 16 | 17 | add_subdirectory(pico-rv32ima) 18 | 19 | add_compile_options(-Wall 20 | -Wno-format # int != int32_t as far as the compiler is concerned because gcc has int32_t as long int 21 | -Wno-unused-function # we have some for the docs that aren't called 22 | -Wno-maybe-uninitialized 23 | ) 24 | 25 | 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pico Linux 2 | 3 | ![MIT License](https://img.shields.io/badge/License-MIT-green.svg) 4 | ![Apache License](https://img.shields.io/badge/license-Apache-blue.svg) 5 | ![BSD-3 License](https://img.shields.io/badge/license-BSD--3-green.svg) 6 | 7 | RISC-V emulator for RP2040, capable of running Linux. 8 | 9 | Based on [pico-rv32ima by tvlad1234](https://github.com/tvlad1234/pico-rv32ima), which is based on [mini-rv32ima by CNLohr](https://github.com/cnlohr/mini-rv32ima). 10 | 11 | ## How It Works 12 | 13 | This project uses [CNLohr's mini-rv32ima](https://github.com/cnlohr/mini-rv32ima) RISC-V emulator core to run Linux on a Raspberry Pi Pico.\ 14 | It uses two 8 megabyte SPI PSRAM chips as system memory. To alleviate the bottleneck introduced by the SPI interface of the PSRAM, a 4kb cache is used.\ 15 | The cache implementation comes from [xhackerustc's uc32-rvima project](https://github.com/xhackerustc/uc-rv32ima). 16 | 17 | ## Usage 18 | 19 | ### Requirements 20 | - a Raspberry Pi Pico (or other RP2040 board) 21 | - an SD card 22 | - two 8 megabyte (64Mbit) SPI PSRAM chips (tvlad1234 used LY68L6400, I used PSRAM64H). 23 | - it is possible to use only one of these chips when running a reduced system image, by changing a setting in the config file. 24 | 25 | _This project overvolts and overclocks the RP2040! Use at own risk!_ 26 | 27 | ### Wiring 28 | The configuration can be modified in the [rv32_config.h](pico-rv32ima/config/rv32_config.h) file. 29 | 30 | - By default, the SD card is connected via SPI, with the following pinout: 31 | - CLK: GPIO18 32 | - MISO: GPIO16 33 | - MOSI: GPIO19 34 | - CS: GPIO20 35 | - The SD card may also be connected over SDIO. 36 | 37 | - The two RAM chips are connected with the following default pinout: 38 | - CLK: GPIO10 39 | - MISO: GPIO12 40 | - MOSI: GPIO11 41 | - CS1: GPIO21 42 | - CS2: GPIO22 43 | - The RAM chips use hardware SPI by default. A flag in the config file allows them to use software bit-banged SPI. 44 | 45 | 46 | ### SD card setup 47 | The SD card needs to be formatted as FAT32 or exFAT. Block sizes from 1024 to 4096 bytes are confirmed to be working. A prebuilt Linux kernel and filesystem image is provided in [this file](linux/Image). It must be placed in the root of the SD card.\ 48 | If you want to build the image yourself, you need to run `make` in the [linux](linux) folder. This will clone the buildroot source tree, apply the necessary config files and build the kernel and system image. 49 | 50 | ### Software 51 | The system console is accessible over USB-CDC, UART or an 128x160 ST7735 display paired with a PS2 keyboard. All three can be used at the same time, but keep in mind they point to the same virtual console. They can be enabled or disabled as desired in the config file. By default, the UART console and LCD console is enabled. 52 | 53 | ## How It Works 54 | 55 | This project uses [CNLohr's mini-rv32ima](https://github.com/cnlohr/mini-rv32ima) RISC-V emulator core to run Linux on a Raspberry Pi Pico.\ 56 | It uses two 8 megabyte SPI PSRAM chips as system memory. To alleviate the bottleneck introduced by the SPI interface of the PSRAM, a 4kb cache is used.\ 57 | The cache implementation comes from [xhackerustc's uc32-rvima project](https://github.com/xhackerustc/uc-rv32ima). 58 | 59 | ## What it does 60 | 61 | The boot process is described below: 62 | - On powerup, the Linux image will be copied into RAM. 63 | - After a few seconds, Linux kernel messages will start streaming on the console. 64 | - After around a minute and half, it will boot into the console 65 | 66 | It uses the RISC-V emulator core to run the compiled Linux kernel on a Raspberry Pi Pico. 67 | 68 | ## Demo 69 | 70 | ### Video 71 | - A video of the boot process can be seen [here]() 72 | 73 | ### Pictures 74 | - Serial (USB or UART) console: 75 | - ![Console boot log](pictures/screenshot.jpg) 76 | - LCD console: 77 | - ![LCD console](pictures/lcd.jpg) 78 | ## Authors 79 | 80 | - [ElectroBoy404NotFound (pico-linux)](https://github.com/ElectroBoy404NotFound/pico-linux) 81 | - [tvlad1234 (pico-rv32ima)](https://github.com/tvlad1234/pico-rv32ima) 82 | - [CNLohr (mini-rv32ima)](https://github.com/cnlohr/mini-rv32ima) 83 | - [xhackerustc (uc32-rvima)](https://github.com/xhackerustc/uc-rv32ima/) 84 | -------------------------------------------------------------------------------- /linux/Image: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElectroBoy404NotFound/pico-linux/5d4eda10c2a3d2b18f0711ebbd690f17bba46fb8/linux/Image -------------------------------------------------------------------------------- /linux/Makefile: -------------------------------------------------------------------------------- 1 | all : image 2 | 3 | buildroot: 4 | git clone https://github.com/tvlad1234/buildroot --recurse-submodules --depth 1 5 | mkdir buildroot/output 6 | mkdir buildroot/output/target 7 | cp -a configs/custom_kernel_config buildroot/kernel_config 8 | cp -a configs/buildroot_config buildroot/.config 9 | cp -a configs/busybox_config buildroot/busybox_config 10 | cp -a configs/rootfsoverlay/* buildroot/output/target/ 11 | 12 | toolchain: 13 | make -C buildroot 14 | 15 | image: toolchain 16 | make -C c4 17 | 18 | updateConfig: 19 | rm configs/custom_kernel_config || true 20 | rm configs/buildroot_config || true 21 | rm configs/busybox_config || true 22 | rm configs/rootfsoverlay/etc/inittab || true 23 | 24 | cp -a buildroot/output/build/linux-6.1.14/.config configs/custom_kernel_config 25 | cp -a buildroot/output/build/busybox-1.36.0/.config configs/busybox_config 26 | cp -a buildroot/output/target/etc/inittab configs/rootfsoverlay/etc/inittab 27 | cp -a buildroot/.config configs/buildroot_config -------------------------------------------------------------------------------- /linux/c4/Makefile: -------------------------------------------------------------------------------- 1 | all : deploy 2 | 3 | PREFIX:=../buildroot/output/host/bin/riscv32-buildroot-linux-uclibc- 4 | CC:=$(PREFIX)gcc 5 | 6 | # Note: regymm says to do -fPIE -pie -static, instead of -fPIC 7 | CFLAGS:=-mabi=ilp32 -fPIE -pie -static -march=rv32ima -Os -s -g 8 | LDFLAGS:=-Wl,-elf2flt=-r 9 | 10 | C_S+=c4src/c4.c 11 | 12 | c4src : 13 | git clone https://github.com/tvlad1234/c4.git c4src 14 | 15 | 16 | c4 : c4src 17 | $(CC) $(CFLAGS) $(C_S) $(LDFLAGS) -o $@ 18 | 19 | deploy : c4 20 | cp $^ ../buildroot/output/target/usr/bin/ 21 | mkdir -p ../buildroot/output/target/usr/src/ 22 | cp $(C_S) ../buildroot/output/target/usr/src/ 23 | cp c4src/hello.c ../buildroot/output/target/root/ 24 | make -C ../buildroot 25 | 26 | clean : 27 | rm -rf c4 c4.gdb 28 | -------------------------------------------------------------------------------- /linux/configs/rootfsoverlay/etc/inittab: -------------------------------------------------------------------------------- 1 | # /etc/inittab 2 | # 3 | # Copyright (C) 2001 Erik Andersen 4 | # 5 | # Note: BusyBox init doesn't support runlevels. The runlevels field is 6 | # completely ignored by BusyBox init. If you want runlevels, use 7 | # sysvinit. 8 | # 9 | # Format for each entry: ::: 10 | # 11 | # id == tty to run on, or empty for /dev/console 12 | # runlevels == ignored 13 | # action == one of sysinit, respawn, askfirst, wait, and once 14 | # process == program to run 15 | 16 | # Startup the system 17 | ::sysinit:/bin/mount -t proc proc /proc 18 | ::sysinit:/bin/mount -o remount,rw / 19 | ::sysinit:/bin/mkdir -p /dev/pts /dev/shm 20 | ::sysinit:/bin/mount -a 21 | ::sysinit:/bin/mkdir -p /run/lock/subsys 22 | #::sysinit:/sbin/swapon -a 23 | null::sysinit:/bin/ln -sf /proc/self/fd /dev/fd 24 | null::sysinit:/bin/ln -sf /proc/self/fd/0 /dev/stdin 25 | null::sysinit:/bin/ln -sf /proc/self/fd/1 /dev/stdout 26 | null::sysinit:/bin/ln -sf /proc/self/fd/2 /dev/stderr 27 | ::sysinit:/bin/hostname -F /etc/hostname 28 | # now run any rc scripts 29 | ::sysinit:/etc/init.d/rcS 30 | 31 | # Put a getty on the serial port 32 | console::sysinit:echo "Welcome to RPi Pico Linux!" 33 | console::respawn:/bin/login -f root 34 | #ttyS0::respawn:/sbin/getty -L ttyS0 115200 vt100 # GENERIC_SERIAL 35 | 36 | # Stuff to do for the 3-finger salute 37 | #::ctrlaltdel:/sbin/reboot 38 | 39 | # Stuff to do before rebooting 40 | ::shutdown:/etc/init.d/rcK 41 | #::shutdown:/sbin/swapoff -a 42 | ::shutdown:/bin/umount -a -r 43 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/.gitignore: -------------------------------------------------------------------------------- 1 | **/build 2 | *.html 3 | *.png 4 | *.zip 5 | *.xlsx 6 | *.bak 7 | **/.vscode 8 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/PlatformIO/bench2/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/PlatformIO/bench2/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/PlatformIO/bench2/lib/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project specific (private) libraries. 3 | PlatformIO will compile them to static libraries and link into executable file. 4 | 5 | The source code of each library should be placed in a an own separate directory 6 | ("lib/your_library_name/[here are source files]"). 7 | 8 | For example, see a structure of the following two libraries `Foo` and `Bar`: 9 | 10 | |--lib 11 | | | 12 | | |--Bar 13 | | | |--docs 14 | | | |--examples 15 | | | |--src 16 | | | |- Bar.c 17 | | | |- Bar.h 18 | | | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html 19 | | | 20 | | |--Foo 21 | | | |- Foo.c 22 | | | |- Foo.h 23 | | | 24 | | |- README --> THIS FILE 25 | | 26 | |- platformio.ini 27 | |--src 28 | |- main.c 29 | 30 | and a contents of `src/main.c`: 31 | ``` 32 | #include 33 | #include 34 | 35 | int main (void) 36 | { 37 | ... 38 | } 39 | 40 | ``` 41 | 42 | PlatformIO Library Dependency Finder will find automatically dependent 43 | libraries scanning project source files. 44 | 45 | More information about PlatformIO Library Dependency Finder 46 | - https://docs.platformio.org/page/librarymanager/ldf.html 47 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/PlatformIO/bench2/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [env:pico] 12 | ; platform = raspberrypi 13 | ; board = pico 14 | ; framework = arduino 15 | 16 | platform = https://github.com/maxgerhardt/platform-raspberrypi.git 17 | board = pico 18 | framework = arduino 19 | board_build.core = earlephilhower 20 | debug_tool = picoprobe 21 | upload_protocol = picoprobe 22 | monitor_port = COM4 23 | monitor_speed = 115200 24 | 25 | build_type = release 26 | 27 | build_flags = 28 | "-Wno-psabi" 29 | -D PICO_STACK_SIZE=0x400 30 | -D __HEAP_SIZE=0x400 31 | -D PICO_USE_STACK_GUARDS=1 32 | -D USE_PRINTF 33 | ; -D USE_DBG_PRINTF 34 | 35 | ; Normal way: 36 | ; lib_deps = 37 | ; carlk3/no-OS-FatFS-SD-SPI-RPi-Pico@^1.0.2 38 | 39 | ; Get the latest straight from github: 40 | ; lib_deps = 41 | ; https://github.com/carlk3/no-OS-FatFS-SD-SPI-RPi-Pico.git#sdio 42 | 43 | ; Use local copy: 44 | lib_deps = 45 | no-OS-FatFS-SD-SPI-RPi-Pico.dev_sdio 46 | lib_extra_dirs = ../../../.. 47 | 48 | ; lib_ldf_mode = deep+ -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/PlatformIO/bench2/test/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for PlatformIO Test Runner and project tests. 3 | 4 | Unit Testing is a software testing method by which individual units of 5 | source code, sets of one or more MCU program modules together with associated 6 | control data, usage procedures, and operating procedures, are tested to 7 | determine whether they are fit for use. Unit testing finds problems early 8 | in the development cycle. 9 | 10 | More information about PlatformIO Unit Testing: 11 | - https://docs.platformio.org/en/latest/advanced/unit-testing/index.html 12 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/PlatformIO/data_logger/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/PlatformIO/data_logger/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [env:pico] 12 | platform = https://github.com/maxgerhardt/platform-raspberrypi.git 13 | board = pico 14 | framework = arduino 15 | board_build.core = earlephilhower 16 | debug_tool = picoprobe 17 | upload_protocol = picoprobe 18 | monitor_port = COM4 19 | monitor_speed = 115200 20 | 21 | build_flags = 22 | "-Wno-psabi" 23 | ; -D USE_PRINTF 24 | ; -D USE_DBG_PRINTF 25 | 26 | ; Normal way: 27 | ; lib_deps = 28 | ; carlk3/no-OS-FatFS-SD-SPI-RPi-Pico@^1.0.2 29 | 30 | ; Get the latest straight from github: 31 | ; lib_deps = 32 | ; https://github.com/carlk3/no-OS-FatFS-SD-SPI-RPi-Pico.git#sdio 33 | 34 | ; Use local copy: 35 | lib_deps = 36 | no-OS-FatFS-SD-SPI-RPi-Pico.dev_sdio 37 | lib_extra_dirs = ../../../.. 38 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/PlatformIO/hw_debug/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/PlatformIO/hw_debug/platformio.ini: -------------------------------------------------------------------------------- 1 | [env:pico] 2 | platform = https://github.com/maxgerhardt/platform-raspberrypi.git 3 | board = pico 4 | framework = arduino 5 | board_build.core = earlephilhower 6 | debug_tool = picoprobe 7 | upload_protocol = picoprobe 8 | monitor_port = COM4 9 | monitor_speed = 115200 10 | 11 | build_flags = 12 | -D USE_PRINTF 13 | -D USE_DBG_PRINTF 14 | 15 | ; Normal way: 16 | ; lib_deps = 17 | ; carlk3/no-OS-FatFS-SD-SPI-RPi-Pico@^1.0.2 18 | 19 | ; Get the latest straight from github: 20 | ; lib_deps = 21 | ; https://github.com/carlk3/no-OS-FatFS-SD-SPI-RPi-Pico.git#sdio 22 | 23 | ; Use local copy: 24 | lib_deps = 25 | no-OS-FatFS-SD-SPI-RPi-Pico.dev_sdio 26 | lib_extra_dirs = ../../../.. 27 | 28 | ; evaluate C/C++ Preprocessor conditional syntax 29 | ; lib_ldf_mode = chain+ 30 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/PlatformIO/one_SDIO/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/PlatformIO/one_SDIO/platformio.ini: -------------------------------------------------------------------------------- 1 | [env:pico] 2 | platform = https://github.com/maxgerhardt/platform-raspberrypi.git 3 | board = pico 4 | framework = arduino 5 | board_build.core = earlephilhower 6 | debug_tool = picoprobe 7 | upload_protocol = picoprobe 8 | monitor_port = COM4 9 | monitor_speed = 115200 10 | 11 | ; build_flags = 12 | 13 | ; Normal way: 14 | ; lib_deps = 15 | ; carlk3/no-OS-FatFS-SD-SPI-RPi-Pico@^1.0.2 16 | 17 | ; Get the latest straight from github: 18 | ; lib_deps = 19 | ; https://github.com/carlk3/no-OS-FatFS-SD-SPI-RPi-Pico.git#sdio 20 | 21 | ; Use local copy: 22 | lib_deps = 23 | no-OS-FatFS-SD-SPI-RPi-Pico.dev_sdio 24 | lib_extra_dirs = ../../../.. 25 | 26 | ; evaluate C/C++ Preprocessor conditional syntax 27 | ; lib_ldf_mode = chain+ 28 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/PlatformIO/one_SDIO/src/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2023 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | 15 | /* Write "Hello, world!\n" to SD Card */ 16 | #include 17 | #include "FatFsSd_C.h" 18 | // 19 | #include "SerialUART.h" 20 | 21 | #define printf Serial1.printf 22 | #define puts Serial1.println 23 | /* 24 | This example assumes the following wiring: 25 | 26 | | GPIO | Pico Pin | microSD | Function | 27 | | ---- | -------- | ------- | ----------- | 28 | | 16 | 21 | DET | Card Detect | 29 | | 17 | 22 | CLK | SDIO_CLK | 30 | | 18 | 24 | CMD | SDIO_CMD | 31 | | 19 | 25 | DAT0 | SDIO_D0 | 32 | | 20 | 26 | DAT1 | SDIO_D1 | 33 | | 21 | 27 | DAT2 | SDIO_D2 | 34 | | 22 | 29 | DAT3 | SDIO_D3 | 35 | */ 36 | // Hardware Configuration of the SD Card "objects" 37 | static sd_card_t sd_cards[] = { // One for each SD card 38 | { 39 | .pcName = "0:", // Name used to mount device 40 | .type = SD_IF_SDIO, 41 | /* 42 | Pins CLK_gpio, D1_gpio, D2_gpio, and D3_gpio are at offsets from pin D0_gpio. 43 | The offsets are determined by sd_driver\SDIO\rp2040_sdio.pio. 44 | CLK_gpio = (D0_gpio + SDIO_CLK_PIN_D0_OFFSET) % 32; 45 | As of this writing, SDIO_CLK_PIN_D0_OFFSET is 30, 46 | which is -2 in mod32 arithmetic, so: 47 | CLK_gpio = D0_gpio -2. 48 | D1_gpio = D0_gpio + 1; 49 | D2_gpio = D0_gpio + 2; 50 | D3_gpio = D0_gpio + 3; 51 | */ 52 | .sdio_if = { 53 | .CMD_gpio = 18, 54 | .D0_gpio = 19, 55 | .SDIO_PIO = pio1, 56 | .DMA_IRQ_num = DMA_IRQ_1 57 | }, 58 | .use_card_detect = true, 59 | .card_detect_gpio = 16, // Card detect 60 | .card_detected_true = 1 // What the GPIO read returns when a card is 61 | // present. 62 | } 63 | }; 64 | /* 65 | The following *get_num, *get_by_num functions are required by the library API. 66 | They are how the library finds out about the configuration. 67 | */ 68 | extern "C" size_t sd_get_num() { return count_of(sd_cards); } 69 | extern "C" sd_card_t *sd_get_by_num(size_t num) { 70 | if (num <= sd_get_num()) { 71 | return &sd_cards[num]; 72 | } else { 73 | return NULL; 74 | } 75 | } 76 | // These need to be defined for the API even if SPI is not used: 77 | extern "C" size_t spi_get_num() { return 0; } 78 | extern "C" spi_t *spi_get_by_num(size_t num) { return NULL; } 79 | 80 | /* ********************************************************************** */ 81 | 82 | // Check the FRESULT of a library call. 83 | // (See http://elm-chan.org/fsw/ff/doc/rc.html.) 84 | #define CHK_FRESULT(s, fr) \ 85 | if (FR_OK != fr) { \ 86 | printf("%s:%d %s error: %s (%d)\n", \ 87 | __FILE__, __LINE__, s, FRESULT_str(fr), fr); \ 88 | for (;;) __breakpoint(); \ 89 | } 90 | 91 | void setup() { 92 | Serial1.begin(115200); // set up Serial library at 9600 bps 93 | while (!Serial1) 94 | ; // Serial is via USB; wait for enumeration 95 | printf("\033[2J\033[H"); // Clear Screen 96 | puts("Hello, world!"); 97 | 98 | // See FatFs - Generic FAT Filesystem Module, "Application Interface", 99 | // http://elm-chan.org/fsw/ff/00index_e.html 100 | sd_card_t *pSD = sd_get_by_num(0); 101 | FRESULT fr = f_mount(&pSD->fatfs, pSD->pcName, 1); 102 | CHK_FRESULT("f_mount", fr); 103 | FIL fil; 104 | const char* const filename = "filename.txt"; 105 | fr = f_open(&fil, filename, FA_OPEN_APPEND | FA_WRITE); 106 | CHK_FRESULT("f_open", fr); 107 | char const * const str = "Hello, world!\n"; 108 | if (f_printf(&fil, str) < strlen(str)) { 109 | printf("f_printf failed\n"); 110 | for (;;) __breakpoint(); 111 | } 112 | fr = f_close(&fil); 113 | CHK_FRESULT("f_close", fr); 114 | fr = f_unmount(pSD->pcName); 115 | CHK_FRESULT("f_unmount", fr); 116 | 117 | puts("Goodbye, world!"); 118 | } 119 | void loop() {} -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/PlatformIO/one_SPI.C++/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/PlatformIO/one_SPI.C++/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [env:pico] 12 | platform = https://github.com/maxgerhardt/platform-raspberrypi.git 13 | board = pico 14 | framework = arduino 15 | board_build.core = earlephilhower 16 | debug_tool = picoprobe 17 | upload_protocol = picoprobe 18 | monitor_port = COM4 19 | monitor_speed = 115200 20 | build_flags = "-Wno-psabi" 21 | 22 | ; Normal way: 23 | ; lib_deps = 24 | ; carlk3/no-OS-FatFS-SD-SPI-RPi-Pico@^1.0.2 25 | 26 | ; Get the latest straight from github: 27 | ; lib_deps = 28 | ; https://github.com/carlk3/no-OS-FatFS-SD-SPI-RPi-Pico.git#sdio 29 | 30 | ; Use local copy: 31 | lib_deps = 32 | no-OS-FatFS-SD-SPI-RPi-Pico.dev_sdio 33 | lib_extra_dirs = ../../../.. 34 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/PlatformIO/one_SPI.C++/src/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2023 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | #include 15 | 16 | #include "FatFsSd.h" 17 | // 18 | #include "SerialUART.h" 19 | #include "iostream/ArduinoStream.h" 20 | 21 | using namespace FatFsNs; 22 | 23 | // Serial output stream 24 | ArduinoOutStream cout(Serial1); 25 | 26 | /* ********************************************************************** */ 27 | 28 | // Check the FRESULT of a library call. 29 | // (See http://elm-chan.org/fsw/ff/doc/rc.html.) 30 | #define CHK_RESULT(s, fr) \ 31 | if (FR_OK != fr) { \ 32 | cout << __FILE__ << ":" << __LINE__ << ": " << s << ": " \ 33 | << FRESULT_str(fr) << " (" << fr << ")" << endl; \ 34 | for (;;) __breakpoint(); \ 35 | } 36 | 37 | void setup() { 38 | Serial1.begin(115200); // set up Serial library 39 | while (!Serial1) 40 | ; // Serial is via USB; wait for enumeration 41 | 42 | /* This example assumes the following wiring: 43 | | signal | SPI1 | GPIO | card | Description | 44 | | ------ | ---- | ---- | ---- | ---------------------- | 45 | | MISO | RX | 12 | DO | Master In, Slave Out | 46 | | CS0 | CSn | 09 | CS | Slave (or Chip) Select | 47 | | SCK | SCK | 14 | SCLK | SPI clock | 48 | | MOSI | TX | 15 | DI | Master Out, Slave In | 49 | | CD | | 13 | DET | Card Detect | 50 | */ 51 | 52 | // GPIO numbers, not Pico pin numbers! 53 | 54 | /* 55 | Hardware Configuration of SPI "objects" 56 | Note: multiple SD cards can be driven by one SPI if they use different slave selects. 57 | Note: None, either or both of the RP2040 SPI components can be used. 58 | */ 59 | 60 | // Hardware Configuration of SPI object 61 | 62 | SpiCfg spi( 63 | spi1, // spi_inst_t *hw_inst, 64 | 12, // uint miso_gpio, 65 | 15, // uint mosi_gpio, 66 | 14, // uint sck_gpio 67 | 25 * 1000 * 1000 // uint baud_rate 68 | ); 69 | spi_handle_t spi_handle(FatFs::add_spi(spi)); 70 | 71 | // Hardware Configuration of the SD Card object 72 | 73 | SdCardSpiCfg spi_sd_card( 74 | spi_handle, // spi_handle_t spi_handle, 75 | "0:", // const char *pcName, 76 | 9, // uint ss_gpio, // Slave select for this SD card 77 | true, // bool use_card_detect = false, 78 | 13, // uint card_detect_gpio = 0, // Card detect; ignored if !use_card_detect 79 | 1 // uint card_detected_true = false // Varies with card socket; ignored if !use_card_detect 80 | ); 81 | 82 | FatFsNs::SdCard* card_p(FatFs::add_sd_card(spi_sd_card)); 83 | 84 | /* ********************************************************************** */ 85 | cout << "\033[2J\033[H"; // Clear Screen 86 | cout << "Hello, world!" << endl; 87 | // sd_card_t* pSD = sd_get_by_num(0); 88 | FRESULT fr = card_p->mount(); 89 | CHK_RESULT("mount", fr); 90 | File file; 91 | char const* const filename = "filename.txt"; 92 | fr = file.open(filename, FA_OPEN_APPEND | FA_WRITE); 93 | CHK_RESULT("open", fr); 94 | char const* const str = "Hello, world!\n"; 95 | if (file.printf(str) < strlen(str)) { 96 | cout << "printf failed\n" 97 | << endl; 98 | for (;;) __breakpoint(); 99 | } 100 | fr = file.close(); 101 | CHK_RESULT("close", fr); 102 | fr = card_p->unmount(); 103 | CHK_RESULT("unmount", fr); 104 | 105 | cout << "Goodbye, world!" << endl; 106 | } 107 | void loop() {} -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/PlatformIO/one_SPI/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/PlatformIO/one_SPI/platformio.ini: -------------------------------------------------------------------------------- 1 | [env:pico] 2 | platform = https://github.com/maxgerhardt/platform-raspberrypi.git 3 | board = pico 4 | framework = arduino 5 | board_build.core = earlephilhower 6 | debug_tool = picoprobe 7 | upload_protocol = picoprobe 8 | monitor_port = COM4 9 | monitor_speed = 115200 10 | 11 | build_flags = 12 | 13 | ; lib_deps = https://github.com/carlk3/no-OS-FatFS-SD-SPI-RPi-Pico.git#sdio 14 | ; Use local copy: 15 | lib_deps = no-OS-FatFS-SD-SPI-RPi-Pico.dev_sdio 16 | lib_extra_dirs = ../../../.. 17 | 18 | ; evaluate C/C++ Preprocessor conditional syntax 19 | ; lib_ldf_mode = chain+ 20 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/PlatformIO/one_SPI/src/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2023 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | 15 | #include "FatFsSd_C.h" 16 | // 17 | #include "SerialUART.h" 18 | 19 | #define printf Serial1.printf 20 | #define puts Serial1.println 21 | 22 | /* ********************************************************************** */ 23 | 24 | /* This example assumes the following wiring: 25 | | signal | SPI1 | GPIO | card | Description | 26 | | ------ | ---- | ---- | ---- | ---------------------- | 27 | | MISO | RX | 12 | DO | Master In, Slave Out | 28 | | CS0 | CSn | 09 | CS | Slave (or Chip) Select | 29 | | SCK | SCK | 14 | SCLK | SPI clock | 30 | | MOSI | TX | 15 | DI | Master Out, Slave In | 31 | | CD | | 13 | DET | Card Detect | 32 | */ 33 | 34 | // Hardware Configuration of SPI "objects" 35 | // Note: multiple SD cards can be driven by one SPI if they use different slave 36 | // selects. 37 | static spi_t spis[] = { // One for each SPI. 38 | { 39 | .hw_inst = spi1, // SPI component 40 | .miso_gpio = 12, // GPIO number (not Pico pin number) 41 | .mosi_gpio = 15, 42 | .sck_gpio = 14, 43 | .baud_rate = 25 * 1000 * 1000, // Actual frequency: 20833333. 44 | .DMA_IRQ_num = DMA_IRQ_0 45 | } 46 | }; 47 | 48 | // Hardware Configuration of the SD Card "objects" 49 | static sd_card_t sd_cards[] = { // One for each SD card 50 | { 51 | .pcName = "0:", // Name used to mount device 52 | .spi_if = { 53 | .spi = &spis[0], // Pointer to the SPI driving this card 54 | .ss_gpio = 9, // The SPI slave select GPIO for this SD card 55 | }, 56 | .use_card_detect = true, 57 | .card_detect_gpio = 13, // Card detect 58 | .card_detected_true = 1 // What the GPIO read returns when a card is 59 | // present. 60 | } 61 | }; 62 | extern "C" size_t sd_get_num() { return count_of(sd_cards); } 63 | extern "C" sd_card_t *sd_get_by_num(size_t num) { 64 | if (num <= sd_get_num()) { 65 | return &sd_cards[num]; 66 | } else { 67 | return NULL; 68 | } 69 | } 70 | extern "C" size_t spi_get_num() { return count_of(spis); } 71 | extern "C" spi_t *spi_get_by_num(size_t num) { 72 | if (num <= spi_get_num()) { 73 | return &spis[num]; 74 | } else { 75 | return NULL; 76 | } 77 | } 78 | 79 | /* ********************************************************************** */ 80 | 81 | void setup() { 82 | Serial1.begin(115200); // set up Serial library at 9600 bps 83 | while (!Serial1) 84 | ; // Serial is via USB; wait for enumeration 85 | time_init(); 86 | 87 | puts("Hello, world!"); 88 | 89 | // See FatFs - Generic FAT Filesystem Module, "Application Interface", 90 | // http://elm-chan.org/fsw/ff/00index_e.html 91 | sd_card_t *pSD = sd_get_by_num(0); 92 | FRESULT fr = f_mount(&pSD->fatfs, pSD->pcName, 1); 93 | if (FR_OK != fr) { 94 | printf("f_mount error: %s (%d)\n", FRESULT_str(fr), fr); 95 | for (;;) __BKPT(1); 96 | } 97 | FIL fil; 98 | const char* const filename = "filename.txt"; 99 | fr = f_open(&fil, filename, FA_OPEN_APPEND | FA_WRITE); 100 | if (FR_OK != fr && FR_EXIST != fr) { 101 | printf("f_open(%s) error: %s (%d)\n", filename, FRESULT_str(fr), fr); 102 | for (;;) __BKPT(2); 103 | } 104 | if (f_printf(&fil, "Hello, world!\n") < 0) { 105 | printf("f_printf failed\n"); 106 | for (;;) __BKPT(3); 107 | } 108 | fr = f_close(&fil); 109 | if (FR_OK != fr) { 110 | printf("f_close error: %s (%d)\n", FRESULT_str(fr), fr); 111 | for (;;) __BKPT(4); 112 | } 113 | f_unmount(pSD->pcName); 114 | 115 | puts("Goodbye, world!"); 116 | } 117 | void loop() {} -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/PlatformIO/one_SPI_one_SDIO.C++/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/PlatformIO/one_SPI_one_SDIO.C++/platformio.ini: -------------------------------------------------------------------------------- 1 | [env:pico] 2 | platform = https://github.com/maxgerhardt/platform-raspberrypi.git 3 | board = pico 4 | framework = arduino 5 | board_build.core = earlephilhower 6 | debug_tool = picoprobe 7 | upload_protocol = picoprobe 8 | monitor_port = COM4 9 | monitor_speed = 115200 10 | 11 | ; build_unflags = -fno-exceptions 12 | ; build_flags = -fexceptions 13 | 14 | build_flags = "-Wno-psabi" 15 | ; "-D USE_PRINTF" 16 | ; "-D USE_DBG_PRINTF" 17 | 18 | ; Normal way: 19 | ; lib_deps = 20 | ; carlk3/no-OS-FatFS-SD-SPI-RPi-Pico@^1.0.2 21 | 22 | ; Get the latest straight from github: 23 | ; lib_deps = 24 | ; https://github.com/carlk3/no-OS-FatFS-SD-SPI-RPi-Pico.git#sdio 25 | 26 | ; Use local copy: 27 | lib_deps = 28 | no-OS-FatFS-SD-SPI-RPi-Pico.dev_sdio 29 | lib_extra_dirs = ../../../.. 30 | 31 | ; evaluate C/C++ Preprocessor conditional syntax 32 | ; lib_ldf_mode = chain+ 33 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/PlatformIO/one_SPI_one_SDIO/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/PlatformIO/one_SPI_one_SDIO/platformio.ini: -------------------------------------------------------------------------------- 1 | [env:pico] 2 | platform = https://github.com/maxgerhardt/platform-raspberrypi.git 3 | board = pico 4 | framework = arduino 5 | board_build.core = earlephilhower 6 | debug_tool = picoprobe 7 | upload_protocol = picoprobe 8 | monitor_port = COM4 9 | monitor_speed = 115200 10 | 11 | ; build_flags = 12 | 13 | ; lib_deps = https://github.com/carlk3/no-OS-FatFS-SD-SPI-RPi-Pico.git#sdio 14 | ; Use local copy: 15 | lib_deps = no-OS-FatFS-SD-SPI-RPi-Pico.dev_sdio 16 | lib_extra_dirs = ../../../.. 17 | 18 | ; evaluate C/C++ Preprocessor conditional syntax 19 | ; lib_ldf_mode = chain+ 20 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/command_line/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | # Pull in Pico SDK (must be before project) 4 | include(pico_sdk_import.cmake) 5 | 6 | project(command_line C CXX ASM) 7 | 8 | set(CMAKE_C_STANDARD 11) 9 | set(CMAKE_CXX_STANDARD 17) 10 | 11 | # add_compile_options(-Os) # Optimize for size (place before pico_sdk_init) 12 | 13 | # Initialise the Pico SDK 14 | pico_sdk_init() 15 | 16 | add_subdirectory(../../src build) 17 | 18 | # Add executable. Default name is the project name, version 0.1 19 | add_executable(command_line 20 | main.cpp 21 | hw_config.c 22 | data_log_demo.c 23 | tests/bench.c 24 | tests/simple.c 25 | tests/app4-IO_module_function_checker.c 26 | tests/big_file_test.c 27 | tests/CreateAndVerifyExampleFiles.c 28 | tests/ff_stdio_tests_with_cwd.c 29 | ) 30 | # Add the standard library to the build 31 | target_link_libraries(command_line pico_stdlib) 32 | 33 | # target_compile_options(command_line PUBLIC -Wall -Wextra -Wno-unused-function -Wno-unused-parameter) 34 | target_compile_options(command_line PUBLIC -Wall -Wextra -Wno-unused-parameter) 35 | 36 | # This program is useless without standard standard input and output. 37 | # add_compile_definitions(USE_PRINTF USE_DBG_PRINTF) 38 | add_compile_definitions(USE_PRINTF) 39 | 40 | set_property(TARGET command_line APPEND_STRING PROPERTY LINK_FLAGS "-Wl,--print-memory-usage") 41 | 42 | pico_set_program_name(command_line "command_line") 43 | pico_set_program_version(command_line "0.1") 44 | 45 | # See 4.1. Serial input and output on Raspberry Pi Pico in Getting started with Raspberry Pi Pico (https://datasheets.raspberrypi.org/pico/getting-started-with-pico.pdf) 46 | # and 2.7.1. Standard Input/Output (stdio) Support in Raspberry Pi Pico C/C++ SDK (https://datasheets.raspberrypi.org/pico/raspberry-pi-pico-c-sdk.pdf): 47 | pico_enable_stdio_uart(command_line 1) 48 | pico_enable_stdio_usb(command_line 1) 49 | 50 | target_link_libraries(command_line 51 | FatFs_SPI 52 | hardware_clocks 53 | hardware_adc 54 | ) 55 | 56 | pico_add_extra_outputs(command_line) 57 | 58 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/command_line/data_log_demo.c: -------------------------------------------------------------------------------- 1 | /* data_log_demo.c 2 | Copyright 2021 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | 15 | #include 16 | #include 17 | #include 18 | // 19 | #include "hardware/adc.h" 20 | #include "pico/stdlib.h" 21 | // 22 | #include "ff.h" 23 | // 24 | #include "f_util.h" 25 | #include "my_debug.h" 26 | 27 | #define DEVICENAME "0:" 28 | 29 | #define TRACE_PRINTF(fmt, args...) 30 | //#define TRACE_PRINTF printf 31 | 32 | static bool print_header(FIL *fp) { 33 | TRACE_PRINTF("%s\n", __func__); 34 | myASSERT(fp); 35 | FRESULT fr = f_lseek(fp, f_size(fp)); 36 | if (FR_OK != fr) { 37 | printf("f_lseek error: %s (%d)\n", FRESULT_str(fr), fr); 38 | return false; 39 | } 40 | if (0 == f_tell(fp)) { 41 | // Print header 42 | if (f_printf(fp, "Date,Time,Temperature (°C)\n") < 0) { 43 | printf("f_printf error\n"); 44 | return false; 45 | } 46 | } 47 | return true; 48 | } 49 | 50 | static bool open_file(FIL *fp) { 51 | TRACE_PRINTF("%s\n", __func__); 52 | myASSERT(fp); 53 | const time_t timer = time(NULL); 54 | struct tm tmbuf; 55 | localtime_r(&timer, &tmbuf); 56 | char filename[64]; 57 | int n = snprintf(filename, sizeof filename, "/data"); 58 | myASSERT(0 < n && n < (int)sizeof filename); 59 | FRESULT fr = f_mkdir(filename); 60 | if (FR_OK != fr && FR_EXIST != fr) { 61 | printf("f_mkdir error: %s (%d)\n", FRESULT_str(fr), fr); 62 | return false; 63 | } 64 | // tm_year int years since 1900 65 | // tm_mon int months since January 0-11 66 | // tm_mday int day of the month 1-31 67 | n += snprintf(filename + n, sizeof filename - n, "/%04d-%02d-%02d", 68 | tmbuf.tm_year + 1900, tmbuf.tm_mon + 1, tmbuf.tm_mday); 69 | myASSERT(0 < n && n < (int)sizeof filename); 70 | fr = f_mkdir(filename); 71 | if (FR_OK != fr && FR_EXIST != fr) { 72 | printf("f_mkdir error: %s (%d)\n", FRESULT_str(fr), fr); 73 | return false; 74 | } 75 | size_t nw = strftime(filename + n, sizeof filename - n, "/%H.csv", &tmbuf); 76 | myASSERT(nw); 77 | fr = f_open(fp, filename, FA_OPEN_APPEND | FA_WRITE); 78 | if (FR_OK != fr && FR_EXIST != fr) { 79 | printf("f_open(%s) error: %s (%d)\n", filename, FRESULT_str(fr), fr); 80 | return false; 81 | } 82 | if (!print_header(fp)) return false; 83 | return true; 84 | } 85 | 86 | bool process_logger() { 87 | TRACE_PRINTF("%s\n", __func__); 88 | /* It's very inefficient to open and close the file for every record, 89 | but you're less likely to lose data that way. But also see f_sync 90 | (http://elm-chan.org/fsw/ff/doc/sync.html). */ 91 | FIL fil; 92 | bool rc = open_file(&fil); 93 | if (!rc) return false; 94 | 95 | // Form date-time string 96 | char buf[128]; 97 | const time_t secs = time(NULL); 98 | struct tm tmbuf; 99 | struct tm *ptm = localtime_r(&secs, &tmbuf); 100 | size_t n = strftime(buf, sizeof buf, "%F,%T,", ptm); 101 | myASSERT(n); 102 | 103 | // The temperature sensor is on input 4: 104 | adc_select_input(4); 105 | uint16_t result = adc_read(); 106 | // 12-bit conversion, assume max value == ADC_VREF == 3.3 V 107 | const float conversion_factor = 3.3f / (1 << 12); 108 | float voltage = conversion_factor * result; 109 | TRACE_PRINTF("Raw value: 0x%03x, voltage: %f V\n", result, (double)voltage); 110 | 111 | // Temperature sensor values can be approximated in centigrade as: 112 | // T = 27 - (ADC_Voltage - 0.706)/0.001721 113 | float Tc = 27.0f - (voltage - 0.706f) / 0.001721f; 114 | TRACE_PRINTF("Temperature: %.1f °C\n", (double)Tc); 115 | int nw = snprintf(buf + n, sizeof buf - n, "%.3g\n", (double)Tc); 116 | myASSERT(0 < nw && nw < (int)sizeof buf); 117 | 118 | if (f_printf(&fil, "%s", buf) < 0) { 119 | printf("f_printf failed\n"); 120 | return false; 121 | } 122 | FRESULT fr = f_close(&fil); 123 | if (FR_OK != fr) { 124 | printf("f_close error: %s (%d)\n", FRESULT_str(fr), fr); 125 | return false; 126 | } 127 | return true; 128 | } 129 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/command_line/hw_config.c: -------------------------------------------------------------------------------- 1 | /* hw_config.c 2 | Copyright 2021 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | /* 15 | 16 | This file should be tailored to match the hardware design. 17 | 18 | There should be one element of the spi[] array for each hardware SPI used. 19 | 20 | There should be one element of the sd_cards[] array for each SD card slot. 21 | The name is should correspond to the FatFs "logical drive" identifier. 22 | (See http://elm-chan.org/fsw/ff/doc/filename.html#vol) 23 | The rest of the constants will depend on the type of 24 | socket, which SPI it is driven by, and how it is wired. 25 | 26 | */ 27 | 28 | #include 29 | // 30 | #include "my_debug.h" 31 | // 32 | #include "hw_config.h" 33 | // 34 | #include "ff.h" /* Obtains integer types */ 35 | // 36 | #include "diskio.h" /* Declarations of disk functions */ 37 | 38 | // Hardware Configuration of SPI "objects" 39 | // Note: multiple SD cards can be driven by one SPI if they use different slave 40 | // selects. 41 | static spi_t spis[] = { // One for each SPI. 42 | { 43 | .hw_inst = spi1, // SPI component 44 | .miso_gpio = 12, // GPIO number (not Pico pin number) 45 | .mosi_gpio = 15, 46 | .sck_gpio = 14, 47 | .set_drive_strength = true, 48 | .mosi_gpio_drive_strength = GPIO_DRIVE_STRENGTH_2MA, 49 | .sck_gpio_drive_strength = GPIO_DRIVE_STRENGTH_2MA, 50 | 51 | .baud_rate = 25 * 1000 * 1000, // Actual frequency: 20833333. 52 | 53 | .DMA_IRQ_num = DMA_IRQ_1, 54 | } 55 | }; 56 | 57 | // Hardware Configuration of the SD Card "objects" 58 | static sd_card_t sd_cards[] = { // One for each SD card 59 | { 60 | .pcName = "0:", // Name used to mount device 61 | .type = SD_IF_SDIO, 62 | /* 63 | Pins CLK_gpio, D1_gpio, D2_gpio, and D3_gpio are at offsets from pin D0_gpio. 64 | The offsets are determined by sd_driver\SDIO\rp2040_sdio.pio. 65 | CLK_gpio = (D0_gpio + SDIO_CLK_PIN_D0_OFFSET) % 32; 66 | As of this writing, SDIO_CLK_PIN_D0_OFFSET is 30, 67 | which is -2 in mod32 arithmetic, so: 68 | CLK_gpio = D0_gpio -2. 69 | D1_gpio = D0_gpio + 1; 70 | D2_gpio = D0_gpio + 2; 71 | D3_gpio = D0_gpio + 3; 72 | */ 73 | .sdio_if = { 74 | .CMD_gpio = 18, 75 | .D0_gpio = 19, 76 | .SDIO_PIO = pio1, 77 | .DMA_IRQ_num = DMA_IRQ_0 78 | }, 79 | .use_card_detect = true, 80 | .card_detect_gpio = 16, // Card detect 81 | .card_detected_true = 1 // What the GPIO read returns when a card is 82 | // present. 83 | }, { 84 | .pcName = "1:", // Name used to mount device 85 | .type = SD_IF_SPI, 86 | .spi_if.spi = &spis[0], // Pointer to the SPI driving this card 87 | .spi_if.ss_gpio = 9, // The SPI slave select GPIO for this SD card 88 | .spi_if.set_drive_strength = true, 89 | .spi_if.ss_gpio_drive_strength = GPIO_DRIVE_STRENGTH_2MA, 90 | .use_card_detect = true, 91 | .card_detect_gpio = 13, // Card detect 92 | .card_detected_true = 1 // What the GPIO read returns when a card is 93 | // present. 94 | } 95 | }; 96 | 97 | /* ********************************************************************** */ 98 | size_t sd_get_num() { return count_of(sd_cards); } 99 | sd_card_t *sd_get_by_num(size_t num) { 100 | if (num <= sd_get_num()) { 101 | return &sd_cards[num]; 102 | } else { 103 | return NULL; 104 | } 105 | } 106 | size_t spi_get_num() { return count_of(spis); } 107 | spi_t *spi_get_by_num(size_t num) { 108 | if (num <= spi_get_num()) { 109 | return &spis[num]; 110 | } else { 111 | return NULL; 112 | } 113 | } 114 | 115 | /* [] END OF FILE */ 116 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/command_line/maker_pi_pico.hw_config.c: -------------------------------------------------------------------------------- 1 | /* hw_config.c 2 | Copyright 2021 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | /* 15 | 16 | This file should be tailored to match the hardware design. 17 | 18 | There should be one element of the spi[] array for each hardware SPI used. 19 | 20 | There should be one element of the sd_cards[] array for each SD card slot. 21 | The name is should correspond to the FatFs "logical drive" identifier. 22 | (See http://elm-chan.org/fsw/ff/doc/filename.html#vol) 23 | The rest of the constants will depend on the type of 24 | socket, which SPI it is driven by, and how it is wired. 25 | 26 | */ 27 | 28 | #include 29 | // 30 | #include "my_debug.h" 31 | // 32 | #include "hw_config.h" 33 | // 34 | #include "ff.h" /* Obtains integer types */ 35 | // 36 | #include "diskio.h" /* Declarations of disk functions */ 37 | 38 | 39 | // Hardware Configuration of SPI "objects" 40 | // Note: multiple SD cards can be driven by one SPI if they use different slave 41 | // selects. 42 | static spi_t spis[] = { // One for each SPI. 43 | { 44 | .hw_inst = spi1, // SPI component 45 | .miso_gpio = 12, // GPIO number (not pin number) 46 | .mosi_gpio = 11, 47 | .sck_gpio = 10, 48 | .baud_rate = 12500 * 1000, 49 | //.baud_rate = 25 * 1000 * 1000, // Actual frequency: 20833333. 50 | } 51 | }; 52 | 53 | // Hardware Configuration of the SD Card "objects" 54 | static sd_card_t sd_cards[] = { // One for each SD card 55 | { 56 | .pcName = "0:", // Name used to mount device 57 | .spi_if.spi = &spis[0], // Pointer to the SPI driving this card 58 | .spi_if.ss_gpio = 15 // The SPI slave select GPIO for this SD card 59 | } 60 | }; 61 | 62 | /* ********************************************************************** */ 63 | size_t sd_get_num() { return count_of(sd_cards); } 64 | sd_card_t *sd_get_by_num(size_t num) { 65 | if (num <= sd_get_num()) { 66 | return &sd_cards[num]; 67 | } else { 68 | return NULL; 69 | } 70 | } 71 | size_t spi_get_num() { return count_of(spis); } 72 | spi_t *spi_get_by_num(size_t num) { 73 | if (num <= spi_get_num()) { 74 | return &spis[num]; 75 | } else { 76 | return NULL; 77 | } 78 | } 79 | 80 | /* [] END OF FILE */ 81 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/command_line/pico_sdk_import.cmake: -------------------------------------------------------------------------------- 1 | # This is a copy of /external/pico_sdk_import.cmake 2 | 3 | # This can be dropped into an external project to help locate this SDK 4 | # It should be include()ed prior to project() 5 | 6 | if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) 7 | set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) 8 | message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") 9 | endif () 10 | 11 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) 12 | set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) 13 | message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") 14 | endif () 15 | 16 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) 17 | set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) 18 | message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") 19 | endif () 20 | 21 | set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") 22 | set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") 23 | set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") 24 | 25 | if (NOT PICO_SDK_PATH) 26 | if (PICO_SDK_FETCH_FROM_GIT) 27 | include(FetchContent) 28 | set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) 29 | if (PICO_SDK_FETCH_FROM_GIT_PATH) 30 | get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") 31 | endif () 32 | FetchContent_Declare( 33 | pico_sdk 34 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 35 | GIT_TAG master 36 | ) 37 | if (NOT pico_sdk) 38 | message("Downloading Raspberry Pi Pico SDK") 39 | FetchContent_Populate(pico_sdk) 40 | set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) 41 | endif () 42 | set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) 43 | else () 44 | message(FATAL_ERROR 45 | "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." 46 | ) 47 | endif () 48 | endif () 49 | 50 | get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") 51 | if (NOT EXISTS ${PICO_SDK_PATH}) 52 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") 53 | endif () 54 | 55 | set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) 56 | if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) 57 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") 58 | endif () 59 | 60 | set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) 61 | 62 | include(${PICO_SDK_INIT_CMAKE_FILE}) 63 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/command_line/tests/tests.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | int lliot(size_t pnum); 9 | void ls(const char *dir); 10 | void simple(); 11 | void bench(char const* logdrv); 12 | void big_file_test(const char *const pathname, size_t size, 13 | uint32_t seed); 14 | void vCreateAndVerifyExampleFiles(const char *pcMountPath); 15 | void vStdioWithCWDTest(const char *pcMountPath); 16 | bool process_logger(); 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/command_line/thing_plus.hw_config.c: -------------------------------------------------------------------------------- 1 | /* hw_config.c 2 | Copyright 2021 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | /* 15 | 16 | This file should be tailored to match the hardware design. 17 | 18 | There should be one element of the spi[] array for each hardware SPI used. 19 | 20 | There should be one element of the sd_cards[] array for each SD card slot. 21 | The name is should correspond to the FatFs "logical drive" identifier. 22 | (See http://elm-chan.org/fsw/ff/doc/filename.html#vol) 23 | The rest of the constants will depend on the type of 24 | socket, which SPI it is driven by, and how it is wired. 25 | 26 | */ 27 | 28 | #include 29 | // 30 | #include "my_debug.h" 31 | // 32 | #include "hw_config.h" 33 | // 34 | #include "ff.h" /* Obtains integer types */ 35 | // 36 | #include "diskio.h" /* Declarations of disk functions */ 37 | 38 | // Hardware Configuration of SPI "objects" 39 | // Note: multiple SD cards can be driven by one SPI if they use different slave 40 | // selects. 41 | static spi_t spis[] = { // One for each SPI. 42 | { 43 | .hw_inst = spi1, // SPI component 44 | .miso_gpio = 12, // GPIO number (not pin number) 45 | .mosi_gpio = 15, 46 | .sck_gpio = 14, 47 | .set_drive_strength = true, 48 | .mosi_gpio_drive_strength = GPIO_DRIVE_STRENGTH_2MA, 49 | .sck_gpio_drive_strength = GPIO_DRIVE_STRENGTH_2MA, 50 | 51 | .baud_rate = 25 * 1000 * 1000, // Actual frequency: 20833333. 52 | } 53 | }; 54 | 55 | // Hardware Configuration of the SD Card "objects" 56 | static sd_card_t sd_cards[] = { // One for each SD card 57 | { 58 | .pcName = "0:", // Name used to mount device 59 | .spi_if.spi = &spis[0], // Pointer to the SPI driving this card 60 | .spi_if.ss_gpio = 9, // The SPI slave select GPIO for this SD card 61 | .spi_if.set_drive_strength = true, 62 | .spi_if.ss_gpio_drive_strength = GPIO_DRIVE_STRENGTH_2MA 63 | } 64 | }; 65 | 66 | /* ********************************************************************** */ 67 | size_t sd_get_num() { return count_of(sd_cards); } 68 | sd_card_t *sd_get_by_num(size_t num) { 69 | if (num <= sd_get_num()) { 70 | return &sd_cards[num]; 71 | } else { 72 | return NULL; 73 | } 74 | } 75 | size_t spi_get_num() { return count_of(spis); } 76 | spi_t *spi_get_by_num(size_t num) { 77 | if (num <= spi_get_num()) { 78 | return &spis[num]; 79 | } else { 80 | return NULL; 81 | } 82 | } 83 | 84 | /* [] END OF FILE */ 85 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/dynamic_config/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Generated Cmake Pico project file 2 | 3 | cmake_minimum_required(VERSION 3.13) 4 | 5 | set(CMAKE_C_STANDARD 11) 6 | set(CMAKE_CXX_STANDARD 17) 7 | 8 | # initalize pico_sdk from installed location 9 | # (note this can come from environment, CMake cache etc) 10 | #set(PICO_SDK_PATH "/home/carlk/pi/pico/pico-sdk") 11 | 12 | # Pull in Raspberry Pi Pico SDK (must be before project) 13 | include(pico_sdk_import.cmake) 14 | 15 | project(dynamic_config_example C CXX ASM) 16 | 17 | # Initialise the Raspberry Pi Pico SDK 18 | pico_sdk_init() 19 | 20 | add_subdirectory(../../src build) 21 | 22 | # Add executable. Default name is the project name, version 0.1 23 | add_executable(dynamic_config_example 24 | main.cpp 25 | ) 26 | 27 | # Can leave these off for silent mode: 28 | #add_compile_definitions(USE_PRINTF USE_DBG_PRINTF) 29 | #add_compile_definitions(USE_PRINTF) 30 | 31 | pico_set_program_name(dynamic_config_example "dynamic_config_example") 32 | pico_set_program_version(dynamic_config_example "0.1") 33 | 34 | # Choose source and destination for standard input and output: 35 | # See 4.1. Serial input and output on Raspberry Pi Pico in Getting started with Raspberry Pi Pico (https://datasheets.raspberrypi.org/pico/getting-started-with-pico.pdf) 36 | # and 2.7.1. Standard Input/Output (stdio) Support in Raspberry Pi Pico C/C++ SDK (https://datasheets.raspberrypi.org/pico/raspberry-pi-pico-c-sdk.pdf): 37 | pico_enable_stdio_uart(dynamic_config_example 1) 38 | pico_enable_stdio_usb(dynamic_config_example 1) 39 | 40 | # Add the standard library and FatFS/SPI to the build 41 | target_link_libraries(dynamic_config_example 42 | pico_stdlib 43 | FatFs_SPI 44 | ) 45 | 46 | pico_add_extra_outputs(dynamic_config_example) 47 | 48 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/dynamic_config/main.cpp: -------------------------------------------------------------------------------- 1 | /* Instead of a statically linked hw_config.c, 2 | create configuration dynamically */ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | // 10 | #include "f_util.h" 11 | #include "ff.h" 12 | #include "pico/stdlib.h" 13 | #include "rtc.h" 14 | // 15 | #include "hw_config.h" 16 | // 17 | #include "diskio.h" /* Declarations of disk functions */ 18 | 19 | static std::vector spis; 20 | static std::vector sd_cards; 21 | 22 | size_t sd_get_num() { return sd_cards.size(); } 23 | sd_card_t *sd_get_by_num(size_t num) { 24 | if (num <= sd_get_num()) { 25 | return sd_cards[num]; 26 | } else { 27 | return NULL; 28 | } 29 | } 30 | 31 | size_t spi_get_num() { return spis.size(); } 32 | spi_t *spi_get_by_num(size_t num) { 33 | if (num <= spi_get_num()) { 34 | return spis[num]; 35 | } else { 36 | return NULL; 37 | } 38 | } 39 | void add_spi(spi_t *spi) { spis.push_back(spi); } 40 | void add_sd_card(sd_card_t *sd_card) { sd_cards.push_back(sd_card); } 41 | 42 | void test(sd_card_t *pSD) { 43 | // See FatFs - Generic FAT Filesystem Module, "Application Interface", 44 | // http://elm-chan.org/fsw/ff/00index_e.html 45 | FRESULT fr = f_mount(&pSD->fatfs, pSD->pcName, 1); 46 | if (FR_OK != fr) panic("f_mount error: %s (%d)\n", FRESULT_str(fr), fr); 47 | fr = f_chdrive(pSD->pcName); 48 | if (FR_OK != fr) panic("f_chdrive error: %s (%d)\n", FRESULT_str(fr), fr); 49 | 50 | FIL fil; 51 | const char *const filename = "filename.txt"; 52 | fr = f_open(&fil, filename, FA_OPEN_APPEND | FA_WRITE); 53 | if (FR_OK != fr && FR_EXIST != fr) 54 | panic("f_open(%s) error: %s (%d)\n", filename, FRESULT_str(fr), fr); 55 | if (f_printf(&fil, "Hello, world!\n") < 0) { 56 | printf("f_printf failed\n"); 57 | } 58 | fr = f_close(&fil); 59 | if (FR_OK != fr) { 60 | printf("f_close error: %s (%d)\n", FRESULT_str(fr), fr); 61 | } 62 | 63 | f_unmount(pSD->pcName); 64 | } 65 | 66 | int main() { 67 | stdio_init_all(); 68 | time_init(); 69 | 70 | puts("Hello, world!"); 71 | 72 | // Hardware Configuration of SPI "object" 73 | spi_t *p_spi = new spi_t; 74 | memset(p_spi, 0, sizeof(spi_t)); 75 | if (!p_spi) panic("Out of memory"); 76 | p_spi->hw_inst = spi1; // SPI component 77 | p_spi->miso_gpio = 12; // GPIO number (not pin number) 78 | p_spi->mosi_gpio = 15; 79 | p_spi->sck_gpio = 14; 80 | p_spi->baud_rate = 25 * 1000 * 1000; // Actual frequency: 20833333. 81 | add_spi(p_spi); 82 | 83 | // Hardware Configuration of the SD Card "object" 84 | sd_card_t *p_sd_card = new sd_card_t; 85 | if (!p_sd_card) panic("Out of memory"); 86 | memset(p_sd_card, 0, sizeof(sd_card_t)); 87 | p_sd_card->pcName = "0:"; // Name used to mount device 88 | p_sd_card->type = SD_IF_SPI, 89 | p_sd_card->spi_if.spi = p_spi; // Pointer to the SPI driving this card 90 | p_sd_card->spi_if.ss_gpio = 9; // The SPI slave select GPIO for this SD card 91 | p_sd_card->use_card_detect = true; 92 | p_sd_card->card_detect_gpio = 13; // Card detect 93 | // What the GPIO read returns when a card is present: 94 | p_sd_card->card_detected_true = 1; 95 | add_sd_card(p_sd_card); 96 | 97 | /* Add another SD card */ 98 | p_sd_card = new sd_card_t; 99 | if (!p_sd_card) panic("Out of memory"); 100 | memset(p_sd_card, 0, sizeof(sd_card_t)); 101 | p_sd_card->pcName = "1:"; // Name used to mount device 102 | p_sd_card->type = SD_IF_SDIO; 103 | /* 104 | Pins CLK_gpio, D1_gpio, D2_gpio, and D3_gpio are at offsets from pin D0_gpio. 105 | The offsets are determined by sd_driver\SDIO\rp2040_sdio.pio. 106 | CLK_gpio = (D0_gpio + SDIO_CLK_PIN_D0_OFFSET) % 32; 107 | As of this writing, SDIO_CLK_PIN_D0_OFFSET is 30, 108 | which is -2 in mod32 arithmetic, so: 109 | CLK_gpio = D0_gpio - 2 110 | D1_gpio = D0_gpio + 1 111 | D2_gpio = D0_gpio + 2 112 | D3_gpio = D0_gpio + 3 113 | */ 114 | p_sd_card->sdio_if.CMD_gpio = 18; 115 | p_sd_card->sdio_if.D0_gpio = 19; 116 | p_sd_card->use_card_detect = true; 117 | p_sd_card->card_detect_gpio = 16; // Card detect 118 | p_sd_card->card_detected_true = 1; // What the GPIO read returns when a card is present. 119 | p_sd_card->sdio_if.SDIO_PIO = pio1; 120 | p_sd_card->sdio_if.DMA_IRQ_num = DMA_IRQ_1; 121 | add_sd_card(p_sd_card); 122 | 123 | for (size_t i = 0; i < sd_get_num(); ++i) 124 | test(sd_get_by_num(i)); 125 | 126 | puts("Goodbye, world!"); 127 | 128 | for (;;) 129 | ; 130 | } 131 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/dynamic_config/pico_sdk_import.cmake: -------------------------------------------------------------------------------- 1 | # This is a copy of /external/pico_sdk_import.cmake 2 | 3 | # This can be dropped into an external project to help locate this SDK 4 | # It should be include()ed prior to project() 5 | 6 | if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) 7 | set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) 8 | message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") 9 | endif () 10 | 11 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) 12 | set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) 13 | message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") 14 | endif () 15 | 16 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) 17 | set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) 18 | message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") 19 | endif () 20 | 21 | set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") 22 | set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") 23 | set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") 24 | 25 | if (NOT PICO_SDK_PATH) 26 | if (PICO_SDK_FETCH_FROM_GIT) 27 | include(FetchContent) 28 | set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) 29 | if (PICO_SDK_FETCH_FROM_GIT_PATH) 30 | get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") 31 | endif () 32 | FetchContent_Declare( 33 | pico_sdk 34 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 35 | GIT_TAG master 36 | ) 37 | if (NOT pico_sdk) 38 | message("Downloading Raspberry Pi Pico SDK") 39 | FetchContent_Populate(pico_sdk) 40 | set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) 41 | endif () 42 | set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) 43 | else () 44 | message(FATAL_ERROR 45 | "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." 46 | ) 47 | endif () 48 | endif () 49 | 50 | get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") 51 | if (NOT EXISTS ${PICO_SDK_PATH}) 52 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") 53 | endif () 54 | 55 | set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) 56 | if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) 57 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") 58 | endif () 59 | 60 | set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) 61 | 62 | include(${PICO_SDK_INIT_CMAKE_FILE}) 63 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/simple/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Generated Cmake Pico project file 2 | 3 | cmake_minimum_required(VERSION 3.13) 4 | 5 | set(CMAKE_C_STANDARD 11) 6 | set(CMAKE_CXX_STANDARD 17) 7 | 8 | # initalize pico_sdk from installed location 9 | # (note this can come from environment, CMake cache etc) 10 | #set(PICO_SDK_PATH "/home/carlk/pi/pico/pico-sdk") 11 | 12 | # Pull in Raspberry Pi Pico SDK (must be before project) 13 | include(pico_sdk_import.cmake) 14 | 15 | project(simple_example C CXX ASM) 16 | 17 | # Initialise the Raspberry Pi Pico SDK 18 | pico_sdk_init() 19 | 20 | add_subdirectory(../../src build) 21 | 22 | # Add executable. Default name is the project name, version 0.1 23 | add_executable(simple_example 24 | main.c 25 | hw_config.c 26 | ) 27 | # Can leave these off for silent mode: 28 | # add_compile_definitions(USE_PRINTF USE_DBG_PRINTF) 29 | add_compile_definitions(USE_PRINTF) 30 | 31 | # Add the standard library and FatFS/SPI to the build 32 | target_link_libraries(simple_example 33 | pico_stdlib 34 | FatFs_SPI 35 | ) 36 | 37 | pico_set_program_name(simple_example "simple_example") 38 | pico_set_program_version(simple_example "0.1") 39 | 40 | # Choose source and destination for standard input and output: 41 | # See 4.1. Serial input and output on Raspberry Pi Pico in Getting started with Raspberry Pi Pico (https://datasheets.raspberrypi.org/pico/getting-started-with-pico.pdf) 42 | # and 2.7.1. Standard Input/Output (stdio) Support in Raspberry Pi Pico C/C++ SDK (https://datasheets.raspberrypi.org/pico/raspberry-pi-pico-c-sdk.pdf): 43 | pico_enable_stdio_uart(simple_example 1) 44 | pico_enable_stdio_usb(simple_example 1) 45 | 46 | pico_add_extra_outputs(simple_example) 47 | 48 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/simple/hw_config.c: -------------------------------------------------------------------------------- 1 | /* hw_config.c 2 | Copyright 2021 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | /* 15 | 16 | This file should be tailored to match the hardware design. 17 | 18 | There should be one element of the spi[] array for each hardware SPI used. 19 | 20 | There should be one element of the sd_cards[] array for each SD card slot. 21 | The name is should correspond to the FatFs "logical drive" identifier. 22 | (See http://elm-chan.org/fsw/ff/doc/filename.html#vol) 23 | The rest of the constants will depend on the type of 24 | socket, which SPI it is driven by, and how it is wired. 25 | 26 | */ 27 | 28 | #include 29 | // 30 | #include "my_debug.h" 31 | // 32 | #include "hw_config.h" 33 | // 34 | #include "ff.h" /* Obtains integer types */ 35 | // 36 | #include "diskio.h" /* Declarations of disk functions */ 37 | 38 | // Hardware Configuration of SPI "objects" 39 | // Note: multiple SD cards can be driven by one SPI if they use different slave 40 | // selects. 41 | static spi_t spis[] = { // One for each SPI. 42 | { 43 | .hw_inst = spi1, // SPI component 44 | .miso_gpio = 12, // GPIO number (not Pico pin number) 45 | .mosi_gpio = 15, 46 | .sck_gpio = 14, 47 | .set_drive_strength = true, 48 | .mosi_gpio_drive_strength = GPIO_DRIVE_STRENGTH_2MA, 49 | .sck_gpio_drive_strength = GPIO_DRIVE_STRENGTH_2MA, 50 | .baud_rate = 25 * 1000 * 1000, // Actual frequency: 20833333. 51 | .DMA_IRQ_num = DMA_IRQ_1 52 | } 53 | }; 54 | 55 | // Hardware Configuration of the SD Card "objects" 56 | static sd_card_t sd_cards[] = { // One for each SD card 57 | { 58 | .pcName = "0:", // Name used to mount device 59 | .spi_if.spi = &spis[0], // Pointer to the SPI driving this card 60 | .spi_if.ss_gpio = 9, // The SPI slave select GPIO for this SD card 61 | 62 | .use_card_detect = true, 63 | .card_detect_gpio = 13, // Card detect 64 | .card_detected_true = 1 // What the GPIO read returns when a card is 65 | // present. 66 | } 67 | }; 68 | 69 | /* ********************************************************************** */ 70 | size_t sd_get_num() { return count_of(sd_cards); } 71 | sd_card_t *sd_get_by_num(size_t num) { 72 | if (num <= sd_get_num()) { 73 | return &sd_cards[num]; 74 | } else { 75 | return NULL; 76 | } 77 | } 78 | size_t spi_get_num() { return count_of(spis); } 79 | spi_t *spi_get_by_num(size_t num) { 80 | if (num <= spi_get_num()) { 81 | return &spis[num]; 82 | } else { 83 | return NULL; 84 | } 85 | } 86 | 87 | /* [] END OF FILE */ 88 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/simple/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | // 3 | #include "f_util.h" 4 | #include "ff.h" 5 | #include "pico/stdlib.h" 6 | #include "rtc.h" 7 | // 8 | #include "hw_config.h" 9 | 10 | int main() { 11 | stdio_init_all(); 12 | time_init(); 13 | 14 | puts("Hello, world!"); 15 | 16 | // See FatFs - Generic FAT Filesystem Module, "Application Interface", 17 | // http://elm-chan.org/fsw/ff/00index_e.html 18 | sd_card_t *pSD = sd_get_by_num(0); 19 | FRESULT fr = f_mount(&pSD->fatfs, pSD->pcName, 1); 20 | if (FR_OK != fr) panic("f_mount error: %s (%d)\n", FRESULT_str(fr), fr); 21 | FIL fil; 22 | const char* const filename = "filename.txt"; 23 | fr = f_open(&fil, filename, FA_OPEN_APPEND | FA_WRITE); 24 | if (FR_OK != fr && FR_EXIST != fr) 25 | panic("f_open(%s) error: %s (%d)\n", filename, FRESULT_str(fr), fr); 26 | if (f_printf(&fil, "Hello, world!\n") < 0) { 27 | printf("f_printf failed\n"); 28 | } 29 | fr = f_close(&fil); 30 | if (FR_OK != fr) { 31 | printf("f_close error: %s (%d)\n", FRESULT_str(fr), fr); 32 | } 33 | f_unmount(pSD->pcName); 34 | 35 | puts("Goodbye, world!"); 36 | for (;;); 37 | } 38 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/simple/pico_sdk_import.cmake: -------------------------------------------------------------------------------- 1 | # This is a copy of /external/pico_sdk_import.cmake 2 | 3 | # This can be dropped into an external project to help locate this SDK 4 | # It should be include()ed prior to project() 5 | 6 | if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) 7 | set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) 8 | message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") 9 | endif () 10 | 11 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) 12 | set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) 13 | message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") 14 | endif () 15 | 16 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) 17 | set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) 18 | message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") 19 | endif () 20 | 21 | set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") 22 | set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") 23 | set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") 24 | 25 | if (NOT PICO_SDK_PATH) 26 | if (PICO_SDK_FETCH_FROM_GIT) 27 | include(FetchContent) 28 | set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) 29 | if (PICO_SDK_FETCH_FROM_GIT_PATH) 30 | get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") 31 | endif () 32 | FetchContent_Declare( 33 | pico_sdk 34 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 35 | GIT_TAG master 36 | ) 37 | if (NOT pico_sdk) 38 | message("Downloading Raspberry Pi Pico SDK") 39 | FetchContent_Populate(pico_sdk) 40 | set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) 41 | endif () 42 | set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) 43 | else () 44 | message(FATAL_ERROR 45 | "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." 46 | ) 47 | endif () 48 | endif () 49 | 50 | get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") 51 | if (NOT EXISTS ${PICO_SDK_PATH}) 52 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") 53 | endif () 54 | 55 | set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) 56 | if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) 57 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") 58 | endif () 59 | 60 | set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) 61 | 62 | include(${PICO_SDK_INIT_CMAKE_FILE}) 63 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/examples/simple/thing_plus.hw_config.c: -------------------------------------------------------------------------------- 1 | /* hw_config.c 2 | Copyright 2021 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | /* 15 | 16 | This file should be tailored to match the hardware design. 17 | 18 | There should be one element of the spi[] array for each hardware SPI used. 19 | 20 | There should be one element of the sd_cards[] array for each SD card slot. 21 | The name is should correspond to the FatFs "logical drive" identifier. 22 | (See http://elm-chan.org/fsw/ff/doc/filename.html#vol) 23 | The rest of the constants will depend on the type of 24 | socket, which SPI it is driven by, and how it is wired. 25 | 26 | */ 27 | 28 | #include 29 | // 30 | #include "my_debug.h" 31 | // 32 | #include "hw_config.h" 33 | // 34 | #include "ff.h" /* Obtains integer types */ 35 | // 36 | #include "diskio.h" /* Declarations of disk functions */ 37 | 38 | void spi_dma_isr(); 39 | 40 | // Hardware Configuration of SPI "objects" 41 | // Note: multiple SD cards can be driven by one SPI if they use different slave 42 | // selects. 43 | static spi_t spis[] = { // One for each SPI. 44 | { 45 | .hw_inst = spi1, // SPI component 46 | .miso_gpio = 12, // GPIO number (not pin number) 47 | .mosi_gpio = 15, 48 | .sck_gpio = 14, 49 | 50 | /* The choice of SD card matters! SanDisk runs at the highest speed. PNY 51 | can only mangage 5 MHz. Those are all I've tried. */ 52 | //.baud_rate = 1000 * 1000, 53 | .baud_rate = 12500 * 1000, // The limitation here is SPI slew rate. 54 | //.baud_rate = 25 * 1000 * 1000, // Actual frequency: 20833333. Has 55 | // worked for me with SanDisk. 56 | 57 | .dma_isr = spi_dma_isr 58 | } 59 | }; 60 | 61 | // Hardware Configuration of the SD Card "objects" 62 | static sd_card_t sd_cards[] = { // One for each SD card 63 | { 64 | .pcName = "0:", // Name used to mount device 65 | .spi = &spis[0], // Pointer to the SPI driving this card 66 | .ss_gpio = 9, // The SPI slave select GPIO for this SD card 67 | //.use_card_detect = false, 68 | .m_Status = STA_NOINIT 69 | } 70 | }; 71 | 72 | void spi_dma_isr() { spi_irq_handler(&spis[0]); } 73 | 74 | /* ********************************************************************** */ 75 | size_t sd_get_num() { return count_of(sd_cards); } 76 | sd_card_t *sd_get_by_num(size_t num) { 77 | if (num <= sd_get_num()) { 78 | return &sd_cards[num]; 79 | } else { 80 | return NULL; 81 | } 82 | } 83 | size_t spi_get_num() { return count_of(spis); } 84 | spi_t *spi_get_by_num(size_t num) { 85 | if (num <= spi_get_num()) { 86 | return &spis[num]; 87 | } else { 88 | return NULL; 89 | } 90 | } 91 | 92 | /* [] END OF FILE */ 93 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/include/FatFsSd_C.h: -------------------------------------------------------------------------------- 1 | /* FatFsSd_C.h 2 | Copyright 2023 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | #pragma once 15 | 16 | // #include "pico/stdlib.h" 17 | // #include "hardware/sync.h" 18 | // #include "pico/sync.h" 19 | // #include "hardware/gpio.h" 20 | // 21 | #include "../src/ff15/source/ff.h" 22 | // 23 | #include "../src/ff15/source/diskio.h" /* Declarations of disk functions */ 24 | #include "../src/include/f_util.h" 25 | #include "../src/include/rtc.h" 26 | #include "../src/sd_driver/sd_card.h" 27 | #include "../src/sd_driver/SDIO/rp2040_sdio.h" 28 | #include "../src/sd_driver/SPI/spi.h" 29 | #include "../src/sd_driver/hw_config.h" -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/include/iostream/ArduinoStream.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2011-2022 Bill Greiman 3 | * This file is part of the SdFat library for SD memory cards. 4 | * 5 | * MIT License 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a 8 | * copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation 10 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | * and/or sell copies of the Software, and to permit persons to whom the 12 | * Software is furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | * DEALINGS IN THE SOFTWARE. 24 | */ 25 | #ifndef ArduinoStream_h 26 | #define ArduinoStream_h 27 | /** 28 | * \file 29 | * \brief ArduinoInStream and ArduinoOutStream classes 30 | */ 31 | #include "bufstream.h" 32 | //============================================================================== 33 | /** 34 | * \class ArduinoInStream 35 | * \brief Input stream for Arduino Stream objects 36 | */ 37 | class ArduinoInStream : public ibufstream { 38 | public: 39 | /** 40 | * Constructor 41 | * \param[in] hws hardware stream 42 | * \param[in] buf buffer for input line 43 | * \param[in] size size of input buffer 44 | */ 45 | ArduinoInStream(Stream &hws, char* buf, size_t size) { 46 | m_hw = &hws; 47 | m_line = buf; 48 | m_size = size; 49 | } 50 | /** read a line. */ 51 | void readline() { 52 | size_t i = 0; 53 | uint32_t t; 54 | m_line[0] = '\0'; 55 | while (!m_hw->available()) { 56 | yield(); 57 | } 58 | 59 | while (1) { 60 | t = millis(); 61 | while (!m_hw->available()) { 62 | if ((millis() - t) > 10) { 63 | goto done; 64 | } 65 | } 66 | if (i >= (m_size - 1)) { 67 | setstate(failbit); 68 | return; 69 | } 70 | m_line[i++] = m_hw->read(); 71 | m_line[i] = '\0'; 72 | } 73 | done: 74 | init(m_line); 75 | } 76 | 77 | protected: 78 | /** Internal - do not use. 79 | * \param[in] off 80 | * \param[in] way 81 | * \return true/false. 82 | */ 83 | bool seekoff(off_type off, seekdir way) { 84 | (void)off; 85 | (void)way; 86 | return false; 87 | } 88 | /** Internal - do not use. 89 | * \param[in] pos 90 | * \return true/false. 91 | */ 92 | bool seekpos(pos_type pos) { 93 | (void)pos; 94 | return false; 95 | } 96 | 97 | private: 98 | char *m_line; 99 | size_t m_size; 100 | Stream* m_hw; 101 | }; 102 | //============================================================================== 103 | /** 104 | * \class ArduinoOutStream 105 | * \brief Output stream for Arduino Print objects 106 | */ 107 | class ArduinoOutStream : public ostream { 108 | public: 109 | /** constructor 110 | * 111 | * \param[in] pr Print object for this ArduinoOutStream. 112 | */ 113 | explicit ArduinoOutStream(print_t& pr) : m_pr(&pr) {} 114 | 115 | protected: 116 | /// @cond SHOW_PROTECTED 117 | /** 118 | * Internal do not use 119 | * \param[in] c 120 | */ 121 | void putch(char c) { 122 | if (c == '\n') { 123 | m_pr->write('\r'); 124 | } 125 | m_pr->write(c); 126 | } 127 | void putstr(const char* str) { 128 | m_pr->write(str); 129 | } 130 | bool seekoff(off_type off, seekdir way) { 131 | (void)off; 132 | (void)way; 133 | return false; 134 | } 135 | bool seekpos(pos_type pos) { 136 | (void)pos; 137 | return false; 138 | } 139 | bool sync() { 140 | return true; 141 | } 142 | pos_type tellpos() { 143 | return 0; 144 | } 145 | /// @endcond 146 | private: 147 | ArduinoOutStream() {} 148 | print_t* m_pr; 149 | }; 150 | #endif // ArduinoStream_h 151 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/include/iostream/StreamBaseClass.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2011-2022 Bill Greiman 3 | * This file is part of the SdFat library for SD memory cards. 4 | * 5 | * MIT License 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a 8 | * copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation 10 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | * and/or sell copies of the Software, and to permit persons to whom the 12 | * Software is furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | * DEALINGS IN THE SOFTWARE. 24 | */ 25 | #include "fstream.h" 26 | //------------------------------------------------------------------------------ 27 | int16_t StreamBaseClass::getch() { 28 | uint8_t c; 29 | int8_t s = StreamBaseFile::read(&c, 1); 30 | if (s != 1) { 31 | if (s < 0) { 32 | setstate(badbit); 33 | } else { 34 | setstate(eofbit); 35 | } 36 | return -1; 37 | } 38 | if (c != '\r' || (getmode() & ios::binary)) { 39 | return c; 40 | } 41 | s = StreamBaseFile::read(&c, 1); 42 | if (s == 1 && c == '\n') { 43 | return c; 44 | } 45 | if (s == 1) { 46 | StreamBaseFile::seekCur(-1); 47 | } 48 | return '\r'; 49 | } 50 | //------------------------------------------------------------------------------ 51 | void StreamBaseClass::open(const char* path, ios::openmode mode) { 52 | oflag_t oflag; 53 | clearWriteError(); 54 | switch (mode & (app | in | out | trunc)) { 55 | case app | in: 56 | case app | in | out: 57 | oflag = O_RDWR | O_APPEND | O_CREAT; 58 | break; 59 | 60 | case app: 61 | case app | out: 62 | oflag = O_WRONLY | O_APPEND | O_CREAT; 63 | break; 64 | 65 | case in: 66 | oflag = O_RDONLY; 67 | break; 68 | 69 | case in | out: 70 | oflag = O_RDWR | O_CREAT; 71 | break; 72 | 73 | case in | out | trunc: 74 | oflag = O_RDWR | O_TRUNC | O_CREAT; 75 | break; 76 | 77 | case out: 78 | case out | trunc: 79 | oflag = O_WRONLY | O_TRUNC | O_CREAT; 80 | break; 81 | 82 | default: 83 | goto fail; 84 | } 85 | if (mode & ios::ate) { 86 | oflag |= O_AT_END; 87 | } 88 | if (!StreamBaseFile::open(path, oflag)) { 89 | goto fail; 90 | } 91 | setmode(mode); 92 | clear(); 93 | return; 94 | 95 | fail: 96 | StreamBaseFile::close(); 97 | setstate(failbit); 98 | return; 99 | } 100 | //------------------------------------------------------------------------------ 101 | void StreamBaseClass::putch(char c) { 102 | if (c == '\n' && !(getmode() & ios::binary)) { 103 | write('\r'); 104 | } 105 | write(c); 106 | if (getWriteError()) { 107 | setstate(badbit); 108 | } 109 | } 110 | //------------------------------------------------------------------------------ 111 | void StreamBaseClass::putstr(const char* str) { 112 | size_t n = 0; 113 | while (1) { 114 | char c = str[n]; 115 | if (c == '\0' || (c == '\n' && !(getmode() & ios::binary))) { 116 | if (n > 0) { 117 | write(str, n); 118 | } 119 | if (c == '\0') { 120 | break; 121 | } 122 | write('\r'); 123 | str += n; 124 | n = 0; 125 | } 126 | n++; 127 | } 128 | if (getWriteError()) { 129 | setstate(badbit); 130 | } 131 | } 132 | //------------------------------------------------------------------------------ 133 | bool StreamBaseClass::seekoff(off_type off, seekdir way) { 134 | pos_type pos; 135 | switch (way) { 136 | case beg: 137 | pos = off; 138 | break; 139 | 140 | case cur: 141 | pos = StreamBaseFile::curPosition() + off; 142 | break; 143 | 144 | case end: 145 | pos = StreamBaseFile::fileSize() + off; 146 | break; 147 | 148 | default: 149 | return false; 150 | } 151 | return seekpos(pos); 152 | } 153 | //------------------------------------------------------------------------------ 154 | int StreamBaseClass::write(const void* buf, size_t n) { 155 | return StreamBaseFile::write(buf, n); 156 | } 157 | //------------------------------------------------------------------------------ 158 | void StreamBaseClass::write(char c) { 159 | StreamBaseFile::write(&c, 1); 160 | } 161 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/include/iostream/iostream.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2011-2022 Bill Greiman 3 | * This file is part of the SdFat library for SD memory cards. 4 | * 5 | * MIT License 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a 8 | * copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation 10 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | * and/or sell copies of the Software, and to permit persons to whom the 12 | * Software is furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | * DEALINGS IN THE SOFTWARE. 24 | */ 25 | #ifndef iostream_h 26 | #define iostream_h 27 | /** 28 | * \file 29 | * \brief \ref iostream class 30 | */ 31 | #include "istream.h" 32 | #include "ostream.h" 33 | /** Skip white space 34 | * \param[in] is the Stream 35 | * \return The stream 36 | */ 37 | inline istream& ws(istream& is) { 38 | is.skipWhite(); 39 | return is; 40 | } 41 | /** insert endline 42 | * \param[in] os The Stream 43 | * \return The stream 44 | */ 45 | inline ostream& endl(ostream& os) { 46 | os.put('\n'); 47 | #if ENDL_CALLS_FLUSH 48 | os.flush(); 49 | #endif // ENDL_CALLS_FLUSH 50 | return os; 51 | } 52 | /** flush manipulator 53 | * \param[in] os The stream 54 | * \return The stream 55 | */ 56 | inline ostream& flush(ostream& os) { 57 | os.flush(); 58 | return os; 59 | } 60 | /** 61 | * \struct setfill 62 | * \brief type for setfill manipulator 63 | */ 64 | struct setfill { 65 | /** fill character */ 66 | char c; 67 | /** constructor 68 | * 69 | * \param[in] arg new fill character 70 | */ 71 | explicit setfill(char arg) : c(arg) {} 72 | }; 73 | /** setfill manipulator 74 | * \param[in] os the stream 75 | * \param[in] arg set setfill object 76 | * \return the stream 77 | */ 78 | inline ostream &operator<< (ostream &os, const setfill &arg) { 79 | os.fill(arg.c); 80 | return os; 81 | } 82 | /** setfill manipulator 83 | * \param[in] obj the stream 84 | * \param[in] arg set setfill object 85 | * \return the stream 86 | */ 87 | inline istream &operator>>(istream &obj, const setfill &arg) { 88 | obj.fill(arg.c); 89 | return obj; 90 | } 91 | //------------------------------------------------------------------------------ 92 | /** \struct setprecision 93 | * \brief type for setprecision manipulator 94 | */ 95 | struct setprecision { 96 | /** precision */ 97 | unsigned int p; 98 | /** constructor 99 | * \param[in] arg new precision 100 | */ 101 | explicit setprecision(unsigned int arg) : p(arg) {} 102 | }; 103 | /** setprecision manipulator 104 | * \param[in] os the stream 105 | * \param[in] arg set setprecision object 106 | * \return the stream 107 | */ 108 | inline ostream &operator<< (ostream &os, const setprecision &arg) { 109 | os.precision(arg.p); 110 | return os; 111 | } 112 | /** setprecision manipulator 113 | * \param[in] is the stream 114 | * \param[in] arg set setprecision object 115 | * \return the stream 116 | */ 117 | inline istream &operator>>(istream &is, const setprecision &arg) { 118 | is.precision(arg.p); 119 | return is; 120 | } 121 | //------------------------------------------------------------------------------ 122 | /** \struct setw 123 | * \brief type for setw manipulator 124 | */ 125 | struct setw { 126 | /** width */ 127 | unsigned w; 128 | /** constructor 129 | * \param[in] arg new width 130 | */ 131 | explicit setw(unsigned arg) : w(arg) {} 132 | }; 133 | /** setw manipulator 134 | * \param[in] os the stream 135 | * \param[in] arg set setw object 136 | * \return the stream 137 | */ 138 | inline ostream &operator<< (ostream &os, const setw &arg) { 139 | os.width(arg.w); 140 | return os; 141 | } 142 | /** setw manipulator 143 | * \param[in] is the stream 144 | * \param[in] arg set setw object 145 | * \return the stream 146 | */ 147 | inline istream &operator>>(istream &is, const setw &arg) { 148 | is.width(arg.w); 149 | return is; 150 | } 151 | //============================================================================== 152 | /** 153 | * \class iostream 154 | * \brief Input/Output stream 155 | */ 156 | class iostream : public istream, public ostream { 157 | }; 158 | #endif // iostream_h 159 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "no-OS-FatFS-SD-SPI-RPi-Pico", 3 | "version": "1.0.6", 4 | "description": "Simple library for SD Cards on the RP2040", 5 | "keywords": ["Data Storage", "FatFs", "SD card", "Secure Digital card", "SPI", "SDIO"], 6 | "repository": 7 | { 8 | "type": "git", 9 | "url": "https://github.com/carlk3/no-OS-FatFS-SD-SPI-RPi-Pico.git#sdio" 10 | }, 11 | "authors": 12 | [ 13 | { 14 | "name": "Carl Kugler", 15 | "email": "carlk3@gmail.com" 16 | } 17 | ], 18 | "license": "Apache-2.0 AND MIT-Modern-Variant", 19 | "frameworks": "arduino", 20 | "platforms": "raspberrypi", 21 | "examples": [ 22 | { 23 | "name": "Example1_one_SD_card_on_SPI", 24 | "base": "examples/PlatformIO/one_SPI.C++", 25 | "files": [ 26 | "platformio.ini", 27 | "src/main.cpp" 28 | ] 29 | }, 30 | { 31 | "name": "Example2_one_SD_card_on_SDIO", 32 | "base": "examples/PlatformIO/one_SDIO", 33 | "files": [ 34 | "platformio.ini", 35 | "src/main.cpp" 36 | ] 37 | }, 38 | { 39 | "name": "Example3_one_SPI_one_SDIO", 40 | "base": "examples/PlatformIO/one_SPI_one_SDIO.C++", 41 | "files": [ 42 | "platformio.ini", 43 | "src/main.cpp" 44 | ] 45 | }, 46 | { 47 | "name": "Example4_data_logger", 48 | "base": "examples/PlatformIO/data_logger", 49 | "files": [ 50 | "platformio.ini", 51 | "src/main.cpp" 52 | ] 53 | }, 54 | { 55 | "name": "Example5_bench", 56 | "base": "examples/PlatformIO/bench2", 57 | "files": [ 58 | "platformio.ini", 59 | "src/main.cpp" 60 | ] 61 | }, 62 | { 63 | "name": "Example6_hw_debug", 64 | "base": "examples/PlatformIO/hw_debug", 65 | "files": [ 66 | "platformio.ini", 67 | "src/main.cpp" 68 | ] 69 | } 70 | ], 71 | "build": { 72 | "srcFilter": [ 73 | "-<.git/> -<.svn/>", 74 | "+", 75 | "+", 76 | "+", 77 | "+", 78 | "+", 79 | "+", 80 | "+", 81 | "+", 82 | "+", 83 | "+", 84 | "+", 85 | "+", 86 | "+", 87 | "+", 88 | "+", 89 | "+" 90 | ], 91 | "flags": [ 92 | "-I include", 93 | "-I src/sd_driver", 94 | "-I src/include", 95 | "-I src/ff15/source", 96 | "-Wno-psabi", 97 | "-D PICO_MAX_SHARED_IRQ_HANDLERS=8u" 98 | ] 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(FatFs_SPI INTERFACE) 2 | 3 | pico_generate_pio_header(FatFs_SPI ${CMAKE_CURRENT_LIST_DIR}/sd_driver/SDIO/rp2040_sdio.pio) 4 | 5 | target_compile_definitions(FatFs_SPI INTERFACE 6 | PICO_MAX_SHARED_IRQ_HANDLERS=8u 7 | ) 8 | 9 | target_sources(FatFs_SPI INTERFACE 10 | ${CMAKE_CURRENT_LIST_DIR}/ff15/source/ff.c 11 | ${CMAKE_CURRENT_LIST_DIR}/ff15/source/ffsystem.c 12 | ${CMAKE_CURRENT_LIST_DIR}/ff15/source/ffunicode.c 13 | ${CMAKE_CURRENT_LIST_DIR}/sd_driver/sd_card.c 14 | ${CMAKE_CURRENT_LIST_DIR}/sd_driver/SDIO/rp2040_sdio.c 15 | ${CMAKE_CURRENT_LIST_DIR}/sd_driver/SDIO/sd_card_sdio.c 16 | ${CMAKE_CURRENT_LIST_DIR}/sd_driver/SPI/crc.c 17 | ${CMAKE_CURRENT_LIST_DIR}/sd_driver/SPI/sd_spi.c 18 | ${CMAKE_CURRENT_LIST_DIR}/sd_driver/SPI/sd_card_spi.c 19 | ${CMAKE_CURRENT_LIST_DIR}/sd_driver/SPI/spi.c 20 | ${CMAKE_CURRENT_LIST_DIR}/source/f_util.c 21 | ${CMAKE_CURRENT_LIST_DIR}/source/ff_stdio.c 22 | ${CMAKE_CURRENT_LIST_DIR}/source/glue.c 23 | ${CMAKE_CURRENT_LIST_DIR}/source/my_debug.c 24 | ${CMAKE_CURRENT_LIST_DIR}/source/rtc.c 25 | ) 26 | target_include_directories(FatFs_SPI INTERFACE 27 | ff15/source 28 | sd_driver 29 | tests 30 | include 31 | ) 32 | target_link_libraries(FatFs_SPI INTERFACE 33 | hardware_dma 34 | hardware_pio 35 | hardware_rtc 36 | hardware_spi 37 | pico_stdlib 38 | cmsis_core 39 | ) 40 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/SdFat/LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2011..2020 Bill Greiman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/SdFat/README.md: -------------------------------------------------------------------------------- 1 | ### Warning: This is SdFat Version 2. 2 | 3 | Earlier releases of Version 1 are here: 4 | 5 | https://github.com/greiman/SdFat/releases 6 | 7 | UTF-8 encoded filenames are supported in v2.1.0 or later. 8 | 9 | Try the UnicodeFilenames example. Here is output from ls: 10 |
 11 | Type any character to begin
 12 | ls:
 13 |          0 😀/
 14 |           20 россиянин
 15 |           17 très élégant
 16 |            9 狗.txt
 17 | 
18 | 19 | SdFat Version 2 supports FAT16/FAT32 and exFAT SD cards. It is mostly 20 | backward compatible with SdFat Version 1 for FAT16/FAT32 cards. 21 | 22 | exFAT supports files larger than 4GB so files sizes and positions are 23 | type uint64_t for classes that support exFAT. 24 | 25 | exFAT has many features not available in FAT16/FAT32. exFAT has excellent 26 | support for contiguous files on flash devices and supports preallocation. 27 | 28 | If the SD card is the only SPI device, use dedicated SPI mode. This can 29 | greatly improve performance. See the bench example. 30 | 31 | Here is write performance for an old, 2011, card on a Due board. 32 | ``` 33 | Shared SPI: 34 | write speed and latency 35 | speed,max,min,avg 36 | KB/Sec,usec,usec,usec 37 | 294.45,24944,1398,1737 38 | 39 | Dedicated SPI: 40 | write speed and latency 41 | speed,max,min,avg 42 | KB/Sec,usec,usec,usec 43 | 3965.11,16733,110,127 44 | ``` 45 | The default version of SdFatConfig.h enables support for dedicated SPI and 46 | optimized access to contiguous files. This makes SdFat Version 2 slightly 47 | larger than Version 1. If these features are disabled, Version 2 is smaller 48 | than Version 1. 49 | 50 | The types for the classes SdFat and File are defined in SdFatConfig.h. 51 | The default version of SdFatConfig.h defines SdFat to only support FAT16/FAT32. 52 | SdFat and File are defined in terms of more basic classes by typedefs. You 53 | can use these basic classes in applications. 54 | 55 | Support for exFAT requires a substantial amount of flash. Here are sizes on 56 | an UNO for a simple program that opens a file, prints one line, and closes 57 | the file. 58 | ``` 59 | FAT16/FAT32 only: 9780 bytes flash, 875 bytes SRAM. 60 | 61 | exFAT only: 13830 bytes flash, 938 bytes SRAM. 62 | 63 | FAT16/FAT32/exFAT: 19326 bytes flash, 928 bytes SRAM. 64 | ``` 65 | The section below of SdFatConfig.h has been edited to uses FAT16/FAT32 for 66 | small AVR boards and FAT16/FAT32/exFAT for all other boards. 67 | ``` 68 | /** 69 | * File types for SdFat, File, SdFile, SdBaseFile, fstream, 70 | * ifstream, and ofstream. 71 | * 72 | * Set SDFAT_FILE_TYPE to: 73 | * 74 | * 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT. 75 | */ 76 | #if defined(__AVR__) && FLASHEND < 0X8000 77 | // FAT16/FAT32 for 32K AVR boards. 78 | #define SDFAT_FILE_TYPE 1 79 | #else // defined(__AVR__) && FLASHEND < 0X8000 80 | // FAT16/FAT32 and exFAT for all other boards. 81 | #define SDFAT_FILE_TYPE 3 82 | #endif // defined(__AVR__) && FLASHEND < 0X8000 83 | ``` 84 | The SdBaseFile class has no Arduino Stream or Print support. 85 | 86 | The File class is derived from Stream and SdBaseFile. 87 | 88 | The SdFile class is derived from SdBaseFile and Print. 89 | 90 | Please try the examples. Start with SdInfo, bench, and ExFatLogger. 91 | 92 | To use SdFat Version 2, unzip the download file, rename the library folder 93 | SdFat and place the SdFat folder into the libraries sub-folder in your main 94 | sketch folder. 95 | 96 | For more information see the Manual installation section of this guide: 97 | 98 | http://arduino.cc/en/Guide/Libraries 99 | 100 | A number of configuration options can be set by editing SdFatConfig.h 101 | define macros. See the html documentation File tab for details. 102 | 103 | Please read the html documentation for this library in SdFat/doc/SdFat.html. 104 | Start with the Main Page. Next go to the Classes tab and read the 105 | documentation for the classes SdFat32, SdExFat, SdFs, File32, ExFile, FsFile. 106 | 107 | The SdFat and File classes are defined in terms of the above classes by 108 | typedefs. Edit SdFatConfig.h to select class options. 109 | 110 | Please continue by reading the html documentation in the SdFat/doc folder. 111 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/ZuluSCSI-firmware/LICENSE: -------------------------------------------------------------------------------- 1 | Software 2 | ----- 3 | 4 | ZuluSCSI™ - Copyright (c) 2022 Rabbit Hole Computing™ 5 | 6 | ZuluSCSI™ is based on both SCSI2SD V6 and BlueSCSI codebases, 7 | and licensed under the GPL version 3 or any later version. 8 | 9 | https://www.gnu.org/licenses/gpl-3.0.html 10 | ---- 11 | SCSI2SD code is Copyright (C) 2016-2022 Michael McMaster. 12 | BlueSCSI code is Copyright (C) 2021 Eric Helgeson. 13 | 14 | This program is free software: you can redistribute it and/or modify 15 | it under the terms of the GNU General Public License as published by 16 | the Free Software Foundation, either version 3 of the License, or 17 | (at your option) any later version. 18 | 19 | This program is distributed in the hope that it will be useful, 20 | but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | GNU General Public License for more details. 23 | 24 | You should have received a copy of the GNU General Public License 25 | along with this program. If not, see . 26 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/ff15/LICENSE.txt: -------------------------------------------------------------------------------- 1 | FatFs License 2 | 3 | FatFs has being developped as a personal project of the author, ChaN. It is free from the code anyone else wrote at current release. Following code block shows a copy of the FatFs license document that heading the source files. 4 | 5 | /*----------------------------------------------------------------------------/ 6 | / FatFs - Generic FAT Filesystem Module Rx.xx / 7 | /-----------------------------------------------------------------------------/ 8 | / 9 | / Copyright (C) 20xx, ChaN, all right reserved. 10 | / 11 | / FatFs module is an open source software. Redistribution and use of FatFs in 12 | / source and binary forms, with or without modification, are permitted provided 13 | / that the following condition is met: 14 | / 15 | / 1. Redistributions of source code must retain the above copyright notice, 16 | / this condition and the following disclaimer. 17 | / 18 | / This software is provided by the copyright holder and contributors "AS IS" 19 | / and any warranties related to this software are DISCLAIMED. 20 | / The copyright owner or contributors be NOT LIABLE for any damages caused 21 | / by use of this software. 22 | /----------------------------------------------------------------------------*/ 23 | 24 | Therefore FatFs license is one of the BSD-style licenses, but there is a significant feature. FatFs is mainly intended for embedded systems. In order to extend the usability for commercial products, the redistributions of FatFs in binary form, such as embedded code, binary library and any forms without source code, do not need to include about FatFs in the documentations. This is equivalent to the 1-clause BSD license. Of course FatFs is compatible with the most of open source software licenses include GNU GPL. When you redistribute the FatFs source code with changes or create a fork, the license can also be changed to GNU GPL, BSD-style license or any open source software license that not conflict with FatFs license. 25 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/ff15/documents/css_e.css: -------------------------------------------------------------------------------- 1 | * {margin: 0; padding: 0; border-width: 0;} 2 | body {margin: 8px; background-color: #e0ffff; font-color: black; font-family: serif; line-height: 133%; max-width: 1024px;} 3 | a:link {color: blue;} 4 | a:visited {color: darkmagenta;} 5 | a:hover {background-color: #a0ffff;} 6 | a:active {color: darkmagenta; overflow: hidden; outline:none; position: relative; top: 1px; left: 1px;} 7 | abbr {border-width: 1px;} 8 | 9 | p {margin: 0 0 0.3em 1em;} 10 | i {margin: 0 0.3em 0 0;} 11 | b {margin: 0 0.1em;} 12 | em {font-style: normal; font-weight: bold; margin: 0 0.1em;} 13 | strong {} 14 | pre {border: 1px dashed gray; margin: 0.5em 1em; padding: 0.5em; line-height: 1.2em; font-size: 85%; font-family: "Consolas", "Courier New", monospace; background-color: white;} 15 | pre span.c {color: green;} 16 | pre span.k {color: blue;} 17 | pre span.e {color: red;} 18 | pre span.b {font-weight: bold;} 19 | pre span.arg {font-style: italic;} 20 | tt {margin: 0 0.2em; font-size: 0.85em; font-family: "Consolas", "Courier New", monospace; } 21 | tt.arg {font-style: italic;} 22 | ol {margin: 0.5em 2.5em;} 23 | ul {margin: 0.5em 2em;} 24 | ul ul {margin: 0 2em 0.5em 1em;} 25 | dl {margin: 0.5em 1em;} 26 | dd {margin: 0 2em;} 27 | dt {font-size: 0.85em; font-family: "Consolas", "Courier New", monospace;} 28 | dl.par dt {margin: 0.5em 0 0 0 ; font-style: italic; } 29 | dl.ret dt {margin: 0.5em 0 0 0 ; font-size: 0.85em; font-family: "Consolas", "Courier New", monospace; font-weight: bold; } 30 | hr {border-width: 1px; margin: 1em;} 31 | div.abst {font-family: sans-serif;} 32 | div.para {clear: both; font-family: serif;} 33 | div.ret a {font-size: 0.85em; font-family: "Consolas", "Courier New", monospace; } 34 | .equ {text-indent: 0; margin: 1em 2em 1em;} 35 | .indent {margin-left: 2em;} 36 | .rset {float: right; margin: 0.3em 0 0.5em 0.5em;} 37 | .lset {float: left; margin: 0.3em 0.5em 0.5em 0.5em;} 38 | ul.flat li {list-style-type: none; margin: 0;} 39 | a.imglnk img {border: 1px solid;} 40 | .iequ {white-space: nowrap; font-weight: bold;} 41 | .clr {clear: both;} 42 | .it {font-style: italic;} 43 | .mfd {font-size: 0.7em; padding: 0 1px; border: 1px solid; white-space : nowrap} 44 | .ral {text-align: right; } 45 | .lal {text-align: left; } 46 | .cal {text-align: center; } 47 | 48 | h1 {line-height: 1em; font-size: 2em; font-family: sans-serif; padding: 0.3em 0 0.3em;} 49 | h2 {font-size: 2em; font-family: sans-serif; background-color: #d8d8FF; padding: 0.5em 0.5em; margin: 0 0 0.5em;} 50 | h3 {font-size: 1.5em; font-family: sans-serif; margin: 1.5em 0 0.5em;} 51 | div.doc h3 {border-color: #b0d8d8; border-style: solid; border-width: 0px 0px 4px 12px; padding: 4px; margin-top: 3em;} 52 | h4 {font-size: 1.2em; font-family: sans-serif; margin: 2em 0 0.2em;} 53 | h5 {font-size: 1em; font-family: sans-serif; margin: 1em 0 0em;} 54 | p.hdd {float: right; text-align: right; margin-top: 0.5em;} 55 | hr.hds {clear: both; margin-bottom: 1em;} 56 | kbd {letter-spacing: 0;} 57 | small {font-size: 80%;} 58 | .indent {margin-left: 2em;} 59 | 60 | /* Tables */ 61 | table {margin: 0.5em 1em; border-collapse: collapse; border: 2px solid gray; } 62 | table caption {font-family: sans-serif; font-weight: bold;} 63 | table th {background-color: white; border-style: solid; border-width: 1px 1px 2px; border-color: gray; padding: 0 3px; vertical-align: top; white-space: nowrap;} 64 | table td {background-color: white; border: 1px solid gray; padding: 0 3px; vertical-align: top; line-height: 1.3em;} 65 | table.lst td:first-child {font-size: 0.85em; font-family: "Consolas", "Courier New", monospace; white-space: nowrap;} 66 | table.lst2 td {font-size: 0.85em; font-family: "Consolas", "Courier New", monospace; white-space: nowrap;} 67 | table.lst3 td {font-family: "Consolas", "Courier New", monospace; white-space: nowrap;} 68 | tr.lst3 td {border-width: 2px 1px 1px; } 69 | table.lst4 td {padding: 0.3em;} 70 | table.lst4 td:nth-child(2) {width: 45%;} 71 | table.lst4 td:nth-child(3) {width: 45%;} 72 | 73 | p.foot {clear: both; text-indent: 0; margin: 1em 0.5em 1em;} 74 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/ff15/documents/res/app1.c: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------/ 2 | / Open or create a file in append mode 3 | / (This function was sperseded by FA_OPEN_APPEND flag at FatFs R0.12a) 4 | /------------------------------------------------------------*/ 5 | 6 | FRESULT open_append ( 7 | FIL* fp, /* [OUT] File object to create */ 8 | const char* path /* [IN] File name to be opened */ 9 | ) 10 | { 11 | FRESULT fr; 12 | 13 | /* Opens an existing file. If not exist, creates a new file. */ 14 | fr = f_open(fp, path, FA_WRITE | FA_OPEN_ALWAYS); 15 | if (fr == FR_OK) { 16 | /* Seek to end of the file to append data */ 17 | fr = f_lseek(fp, f_size(fp)); 18 | if (fr != FR_OK) 19 | f_close(fp); 20 | } 21 | return fr; 22 | } 23 | 24 | 25 | int main (void) 26 | { 27 | FRESULT fr; 28 | FATFS fs; 29 | FIL fil; 30 | 31 | /* Open or create a log file and ready to append */ 32 | f_mount(&fs, "", 0); 33 | fr = open_append(&fil, "logfile.txt"); 34 | if (fr != FR_OK) return 1; 35 | 36 | /* Append a line */ 37 | f_printf(&fil, "%02u/%02u/%u, %2u:%02u\n", Mday, Mon, Year, Hour, Min); 38 | 39 | /* Close the file */ 40 | f_close(&fil); 41 | 42 | return 0; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/ff15/documents/res/app2.c: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------/ 2 | / Delete a sub-directory even if it contains any file 3 | /-------------------------------------------------------------/ 4 | / The delete_node() function is for R0.12+. 5 | / It works regardless of FF_FS_RPATH. 6 | */ 7 | 8 | 9 | FRESULT delete_node ( 10 | TCHAR* path, /* Path name buffer with the sub-directory to delete */ 11 | UINT sz_buff, /* Size of path name buffer (items) */ 12 | FILINFO* fno /* Name read buffer */ 13 | ) 14 | { 15 | UINT i, j; 16 | FRESULT fr; 17 | DIR dir; 18 | 19 | 20 | fr = f_opendir(&dir, path); /* Open the sub-directory to make it empty */ 21 | if (fr != FR_OK) return fr; 22 | 23 | for (i = 0; path[i]; i++) ; /* Get current path length */ 24 | path[i++] = _T('/'); 25 | 26 | for (;;) { 27 | fr = f_readdir(&dir, fno); /* Get a directory item */ 28 | if (fr != FR_OK || !fno->fname[0]) break; /* End of directory? */ 29 | j = 0; 30 | do { /* Make a path name */ 31 | if (i + j >= sz_buff) { /* Buffer over flow? */ 32 | fr = 100; break; /* Fails with 100 when buffer overflow */ 33 | } 34 | path[i + j] = fno->fname[j]; 35 | } while (fno->fname[j++]); 36 | if (fno->fattrib & AM_DIR) { /* Item is a sub-directory */ 37 | fr = delete_node(path, sz_buff, fno); 38 | } else { /* Item is a file */ 39 | fr = f_unlink(path); 40 | } 41 | if (fr != FR_OK) break; 42 | } 43 | 44 | path[--i] = 0; /* Restore the path name */ 45 | f_closedir(&dir); 46 | 47 | if (fr == FR_OK) fr = f_unlink(path); /* Delete the empty sub-directory */ 48 | return fr; 49 | } 50 | 51 | 52 | 53 | 54 | int main (void) /* How to use */ 55 | { 56 | FRESULT fr; 57 | FATFS fs; 58 | TCHAR buff[256]; 59 | FILINFO fno; 60 | 61 | 62 | f_mount(&fs, _T("5:"), 0); 63 | 64 | /* Directory to be deleted */ 65 | _tcscpy(buff, _T("5:dir")); 66 | 67 | /* Delete the directory */ 68 | fr = delete_node(buff, sizeof buff / sizeof buff[0], &fno); 69 | 70 | /* Check the result */ 71 | if (fr) { 72 | _tprintf(_T("Failed to delete the directory. (%u)\n"), fr); 73 | return fr; 74 | } else { 75 | _tprintf(_T("The directory and the contents have successfully been deleted.\n"), buff); 76 | return 0; 77 | } 78 | } 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/ff15/documents/res/app3.c: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------/ 2 | / Allocate a contiguous area to the file 3 | /-----------------------------------------------------------------------/ 4 | / This function checks if the file is contiguous with desired size. 5 | / If not, a block of contiguous sectors is allocated to the file. 6 | / If the file has been opened without FA_WRITE flag, it only checks if 7 | / the file is contiguous and returns the resulut. 8 | /-----------------------------------------------------------------------/ 9 | / This function can work with FatFs R0.09 - R0.11a. 10 | / It is incompatible with R0.12+. Use f_expand function instead. 11 | /----------------------------------------------------------------------*/ 12 | 13 | /* Declarations of FatFs internal functions accessible from applications. 14 | / This is intended to be used for disk checking/fixing or dirty hacks :-) */ 15 | DWORD clust2sect (FATFS* fs, DWORD clst); 16 | DWORD get_fat (FATFS* fs, DWORD clst); 17 | FRESULT put_fat (FATFS* fs, DWORD clst, DWORD val); 18 | 19 | 20 | DWORD allocate_contiguous_clusters ( /* Returns the first sector in LBA (0:error or not contiguous) */ 21 | FIL* fp, /* Pointer to the open file object */ 22 | DWORD len /* Number of bytes to allocate */ 23 | ) 24 | { 25 | DWORD csz, tcl, ncl, ccl, cl; 26 | 27 | 28 | if (f_lseek(fp, 0) || !len) /* Check if the given parameters are valid */ 29 | return 0; 30 | csz = 512UL * fp->fs->csize; /* Cluster size in unit of byte (assuming 512 bytes/sector) */ 31 | tcl = (len + csz - 1) / csz; /* Total number of clusters required */ 32 | len = tcl * csz; /* Round-up file size to the cluster boundary */ 33 | 34 | /* Check if the existing cluster chain is contiguous */ 35 | if (len == fp->fsize) { 36 | ncl = 0; ccl = fp->sclust; 37 | do { 38 | cl = get_fat(fp->fs, ccl); /* Get the cluster status */ 39 | if (cl + 1 < 3) return 0; /* Hard error? */ 40 | if (cl != ccl + 1 && cl < fp->fs->n_fatent) break; /* Not contiguous? */ 41 | ccl = cl; 42 | } while (++ncl < tcl); 43 | if (ncl == tcl) /* Is the file contiguous? */ 44 | return clust2sect(fp->fs, fp->sclust); /* File is contiguous. Return the start sector */ 45 | } 46 | 47 | /* File is not contiguous */ 48 | #if _FS_READONLY 49 | return 0; /* Exit if in read-only cfg. */ 50 | #else 51 | if (!(fp->flag & FA_WRITE)) return 0; /* Exit if the file object is for read-only */ 52 | 53 | if (f_truncate(fp)) return 0; /* Remove the non-contiguous chain */ 54 | 55 | /* Find a free contiguous area */ 56 | ccl = cl = 2; ncl = 0; 57 | do { 58 | if (cl >= fp->fs->n_fatent) return 0; /* No contiguous area is found. */ 59 | if (get_fat(fp->fs, cl)) { /* Encounterd a cluster in use */ 60 | do { /* Skip the block of used clusters */ 61 | cl++; 62 | if (cl >= fp->fs->n_fatent) return 0; /* No contiguous area is found. */ 63 | } while (get_fat(fp->fs, cl)); 64 | ccl = cl; ncl = 0; 65 | } 66 | cl++; ncl++; 67 | } while (ncl < tcl); 68 | 69 | /* Create a contiguous cluster chain */ 70 | fp->fs->last_clust = ccl - 1; 71 | if (f_lseek(fp, len)) return 0; 72 | 73 | return clust2sect(fp->fs, fp->sclust); /* Return file start sector */ 74 | #endif 75 | } 76 | 77 | 78 | int main (void) 79 | { 80 | FRESULT fr; 81 | DRESULT dr; 82 | FATFS fs; 83 | FIL fil; 84 | DWORD org; 85 | 86 | 87 | /* Open or create a file to write */ 88 | f_mount(&fs, "", 0); 89 | fr = f_open(&fil, "fastrec.log", FA_READ | FA_WRITE | FA_OPEN_ALWAYS); 90 | if (fr) return 1; 91 | 92 | /* Check if the file is 256MB in size and occupies a contiguous area. 93 | / If not, a contiguous area will be re-allocated to the file. */ 94 | org = allocate_contiguous_clusters(&fil, 0x10000000); 95 | if (!org) { 96 | printf("Function failed due to any error or insufficient contiguous area.\n"); 97 | f_close(&fil); 98 | return 1; 99 | } 100 | 101 | /* Now you can read/write the file without filesystem layer. */ 102 | ... 103 | dr = disk_write(fil.fs->drv, Buff, org, 1024); /* Write 512KiB from top of the file */ 104 | ... 105 | 106 | f_close(&fil); 107 | return 0; 108 | } 109 | 110 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/ff15/documents/res/app5.c: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------/ 2 | / Test if the file is contiguous / 3 | /----------------------------------------------------------------------*/ 4 | 5 | FRESULT test_contiguous_file ( 6 | FIL* fp, /* [IN] Open file object to be checked */ 7 | int* cont /* [OUT] 1:Contiguous, 0:Fragmented or zero-length */ 8 | ) 9 | { 10 | DWORD clst, clsz, step; 11 | FSIZE_t fsz; 12 | FRESULT fr; 13 | 14 | 15 | *cont = 0; 16 | fr = f_rewind(fp); /* Validates and prepares the file */ 17 | if (fr != FR_OK) return fr; 18 | 19 | #if FF_MAX_SS == FF_MIN_SS 20 | clsz = (DWORD)fp->obj.fs->csize * FF_MAX_SS; /* Cluster size */ 21 | #else 22 | clsz = (DWORD)fp->obj.fs->csize * fp->obj.fs->ssize; 23 | #endif 24 | fsz = f_size(fp); 25 | if (fsz > 0) { 26 | clst = fp->obj.sclust - 1; /* A cluster leading the first cluster for first test */ 27 | while (fsz) { 28 | step = (fsz >= clsz) ? clsz : (DWORD)fsz; 29 | fr = f_lseek(fp, f_tell(fp) + step); /* Advances file pointer a cluster */ 30 | if (fr != FR_OK) return fr; 31 | if (clst + 1 != fp->clust) break; /* Is not the cluster next to previous one? */ 32 | clst = fp->clust; fsz -= step; /* Get current cluster for next test */ 33 | } 34 | if (fsz == 0) *cont = 1; /* All done without fail? */ 35 | } 36 | 37 | return FR_OK; 38 | } 39 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/ff15/documents/res/app6.c: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------*/ 2 | /* Raw Read/Write Throughput Checker */ 3 | /*---------------------------------------------------------------------*/ 4 | 5 | #include 6 | #include 7 | #include "diskio.h" 8 | #include "ff.h" 9 | 10 | 11 | int test_raw_speed ( 12 | BYTE pdrv, /* Physical drive number */ 13 | DWORD lba, /* Start LBA for read/write test */ 14 | DWORD len, /* Number of bytes to read/write (must be multiple of sz_buff) */ 15 | void* buff, /* Read/write buffer */ 16 | UINT sz_buff /* Size of read/write buffer (must be multiple of FF_MAX_SS) */ 17 | ) 18 | { 19 | WORD ss; 20 | DWORD ofs, tmr; 21 | 22 | 23 | #if FF_MIN_SS != FF_MAX_SS 24 | if (disk_ioctl(pdrv, GET_SECTOR_SIZE, &ss) != RES_OK) { 25 | printf("\ndisk_ioctl() failed.\n"); 26 | return 0; 27 | } 28 | #else 29 | ss = FF_MAX_SS; 30 | #endif 31 | 32 | printf("Starting raw write test at sector %lu in %u bytes of data chunks...", lba, sz_buff); 33 | tmr = systimer(); 34 | for (ofs = 0; ofs < len / ss; ofs += sz_buff / ss) { 35 | if (disk_write(pdrv, buff, lba + ofs, sz_buff / ss) != RES_OK) { 36 | printf("\ndisk_write() failed.\n"); 37 | return 0; 38 | } 39 | } 40 | if (disk_ioctl(pdrv, CTRL_SYNC, 0) != RES_OK) { 41 | printf("\ndisk_ioctl() failed.\n"); 42 | return 0; 43 | } 44 | tmr = systimer() - tmr; 45 | printf("\n%lu bytes written and it took %lu timer ticks.\n", len, tmr); 46 | 47 | printf("Starting raw read test at sector %lu in %u bytes of data chunks...", lba, sz_buff); 48 | tmr = systimer(); 49 | for (ofs = 0; ofs < len / ss; ofs += sz_buff / ss) { 50 | if (disk_read(pdrv, buff, lba + ofs, sz_buff / ss) != RES_OK) { 51 | printf("\ndisk_read() failed.\n"); 52 | return 0; 53 | } 54 | } 55 | tmr = systimer() - tmr; 56 | printf("\n%lu bytes read and it took %lu timer ticks.\n", len, tmr); 57 | 58 | printf("Test completed.\n"); 59 | return 1; 60 | } 61 | 62 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/ff15/source/00readme.txt: -------------------------------------------------------------------------------- 1 | FatFs Module Source Files R0.15 2 | 3 | 4 | FILES 5 | 6 | 00readme.txt This file. 7 | 00history.txt Revision history. 8 | ff.c FatFs module. 9 | ffconf.h Configuration file of FatFs module. 10 | ff.h Common include file for FatFs and application module. 11 | diskio.h Common include file for FatFs and disk I/O module. 12 | diskio.c An example of glue function to attach existing disk I/O module to FatFs. 13 | ffunicode.c Optional Unicode utility functions. 14 | ffsystem.c An example of optional O/S related functions. 15 | 16 | 17 | Low level disk I/O module is not included in this archive because the FatFs 18 | module is only a generic file system layer and it does not depend on any specific 19 | storage device. You need to provide a low level disk I/O module written to 20 | control the storage device that attached to the target system. 21 | 22 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/ff15/source/diskio.h: -------------------------------------------------------------------------------- 1 | /*-----------------------------------------------------------------------/ 2 | / Low level disk interface modlue include file (C)ChaN, 2019 / 3 | /-----------------------------------------------------------------------*/ 4 | 5 | #ifndef _DISKIO_DEFINED 6 | #define _DISKIO_DEFINED 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | /* Status of Disk Functions */ 13 | typedef BYTE DSTATUS; 14 | 15 | /* Results of Disk Functions */ 16 | typedef enum { 17 | RES_OK = 0, /* 0: Successful */ 18 | RES_ERROR, /* 1: R/W Error */ 19 | RES_WRPRT, /* 2: Write Protected */ 20 | RES_NOTRDY, /* 3: Not Ready */ 21 | RES_PARERR /* 4: Invalid Parameter */ 22 | } DRESULT; 23 | 24 | 25 | /*---------------------------------------*/ 26 | /* Prototypes for disk control functions */ 27 | 28 | 29 | DSTATUS disk_initialize (BYTE pdrv); 30 | DSTATUS disk_status (BYTE pdrv); 31 | DRESULT disk_read (BYTE pdrv, BYTE* buff, LBA_t sector, UINT count); 32 | DRESULT disk_write (BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count); 33 | DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff); 34 | 35 | 36 | /* Disk Status Bits (DSTATUS) */ 37 | 38 | #define STA_NOINIT 0x01 /* Drive not initialized */ 39 | #define STA_NODISK 0x02 /* No medium in the drive */ 40 | #define STA_PROTECT 0x04 /* Write protected */ 41 | 42 | 43 | /* Command code for disk_ioctrl fucntion */ 44 | 45 | /* Generic command (Used by FatFs) */ 46 | #define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */ 47 | #define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */ 48 | #define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */ 49 | #define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */ 50 | #define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */ 51 | 52 | /* Generic command (Not used by FatFs) */ 53 | #define CTRL_POWER 5 /* Get/Set power status */ 54 | #define CTRL_LOCK 6 /* Lock/Unlock media removal */ 55 | #define CTRL_EJECT 7 /* Eject media */ 56 | #define CTRL_FORMAT 8 /* Create physical format on the media */ 57 | 58 | /* MMC/SDC specific ioctl command */ 59 | #define MMC_GET_TYPE 10 /* Get card type */ 60 | #define MMC_GET_CSD 11 /* Get CSD */ 61 | #define MMC_GET_CID 12 /* Get CID */ 62 | #define MMC_GET_OCR 13 /* Get OCR */ 63 | #define MMC_GET_SDSTAT 14 /* Get SD status */ 64 | #define ISDIO_READ 55 /* Read data form SD iSDIO register */ 65 | #define ISDIO_WRITE 56 /* Write data to SD iSDIO register */ 66 | #define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */ 67 | 68 | /* ATA/CF specific ioctl command */ 69 | #define ATA_GET_REV 20 /* Get F/W revision */ 70 | #define ATA_GET_MODEL 21 /* Get model name */ 71 | #define ATA_GET_SN 22 /* Get serial number */ 72 | 73 | #ifdef __cplusplus 74 | } 75 | #endif 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/include/f_util.h: -------------------------------------------------------------------------------- 1 | /* f_util.h 2 | Copyright 2021 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | #pragma once 15 | #include "ff.h" 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | const char *FRESULT_str(FRESULT i); 22 | FRESULT delete_node ( 23 | TCHAR* path, /* Path name buffer with the sub-directory to delete */ 24 | UINT sz_buff, /* Size of path name buffer (items) */ 25 | FILINFO* fno /* Name read buffer */ 26 | ); 27 | 28 | #ifdef __cplusplus 29 | } 30 | #endif 31 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/include/ff_stdio.h: -------------------------------------------------------------------------------- 1 | /* ff_stdio.h 2 | Copyright 2021 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | // For compatibility with FreeRTOS+FAT API 15 | #include 16 | #include 17 | #include 18 | #include 19 | // 20 | #include "ff.h" 21 | // 22 | #include "my_debug.h" 23 | 24 | #define BaseType_t int 25 | #define FF_FILE FIL 26 | 27 | #define ff_rewind f_rewind 28 | #define pvPortMalloc malloc 29 | #define vPortFree free 30 | #define ffconfigMAX_FILENAME 250 31 | #define configASSERT myASSERT 32 | #define FF_PRINTF printf 33 | #define pdFREERTOS_ERRNO_NONE 0 34 | #define FF_EOF (-1) 35 | #define FF_SEEK_SET 0 36 | #define FF_SEEK_CUR 1 37 | #define FF_SEEK_END 2 38 | #define pdFALSE 0 39 | #define pdTRUE 1 40 | #define ff_filelength f_size 41 | #define ff_feof f_eof 42 | 43 | typedef struct FF_STAT { 44 | uint32_t st_size; /* Size of the object in number of bytes. */ 45 | // uint16_t st_mode; /* The mode (attribute bits) of this 46 | // file or directory. */ 47 | } FF_Stat_t; 48 | 49 | typedef struct { 50 | DIR dir; 51 | FILINFO fileinfo; 52 | const char *pcFileName; 53 | uint32_t ulFileSize; 54 | //uint8_t ucAttributes; 55 | } FF_FindData_t; 56 | 57 | FF_FILE *ff_fopen(const char *pcFile, const char *pcMode); 58 | int ff_fclose(FF_FILE *pxStream); 59 | int ff_stat(const char *pcFileName, FF_Stat_t *pxStatBuffer); 60 | size_t ff_fwrite(const void *pvBuffer, size_t xSize, size_t xItems, 61 | FF_FILE *pxStream); 62 | size_t ff_fread(void *pvBuffer, size_t xSize, size_t xItems, FF_FILE *pxStream); 63 | int ff_chdir(const char *pcDirectoryName); 64 | char *ff_getcwd(char *pcBuffer, size_t xBufferLength); 65 | int ff_mkdir(const char *pcPath); 66 | int ff_fputc(int iChar, FF_FILE *pxStream); 67 | int ff_fgetc(FF_FILE *pxStream); 68 | int ff_rmdir(const char *pcDirectory); 69 | int ff_remove(const char *pcPath); 70 | long ff_ftell(FF_FILE *pxStream); 71 | int ff_fseek(FF_FILE *pxStream, int iOffset, int iWhence); 72 | int ff_findfirst(const char *pcDirectory, FF_FindData_t *pxFindData); 73 | int ff_findnext( FF_FindData_t *pxFindData ); 74 | FF_FILE *ff_truncate( const char * pcFileName, long lTruncateSize ); 75 | int ff_seteof( FF_FILE *pxStream ); 76 | int ff_rename( const char *pcOldName, const char *pcNewName, int bDeleteIfExists ); 77 | char *ff_fgets(char *pcBuffer, size_t xCount, FF_FILE *pxStream); 78 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/include/ffconf.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElectroBoy404NotFound/pico-linux/5d4eda10c2a3d2b18f0711ebbd690f17bba46fb8/no-OS-FatFS-SD-SPI-RPi-Pico/src/include/ffconf.h -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/include/my_debug.h: -------------------------------------------------------------------------------- 1 | /* my_debug.h 2 | Copyright 2021 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | #pragma once 15 | 16 | #ifdef USE_PRINTF 17 | # include 18 | #else 19 | # define printf(...) // Do nothing 20 | # define puts(...) 21 | # define fflush(...) 22 | #endif 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | void my_printf(const char *pcFormat, ...) __attribute__((format(__printf__, 1, 2))); 29 | 30 | void my_assert_func(const char *file, int line, const char *func, 31 | const char *pred); 32 | 33 | #ifdef __cplusplus 34 | } 35 | #endif 36 | 37 | //#if defined(DEBUG) && !defined(NDEBUG) 38 | // #define DBG_PRINTF my_printf 39 | //#else 40 | 41 | #if defined(USE_DBG_PRINTF) 42 | # define DBG_PRINTF my_printf 43 | #else 44 | # define DBG_PRINTF(fmt, args...) {} /* Don't do anything in release builds*/ 45 | #endif 46 | 47 | #define myASSERT(__e) \ 48 | { ((__e) ? (void)0 : my_assert_func(__FILE__, __LINE__, __func__, #__e)); } 49 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/include/rtc.h: -------------------------------------------------------------------------------- 1 | /* rtc.h 2 | Copyright 2021 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | #pragma once 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | void time_init(); 21 | 22 | #ifdef __cplusplus 23 | } 24 | #endif 25 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/include/util.h: -------------------------------------------------------------------------------- 1 | /* util.h 2 | Copyright 2021 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | #ifndef _UTIL_H_ 15 | #define _UTIL_H_ 16 | 17 | #include 18 | #include 19 | #include "hardware/structs/scb.h" 20 | #include "RP2040.h" 21 | #include "my_debug.h" 22 | 23 | // works with negative index 24 | static inline int wrap_ix(int index, int n) 25 | { 26 | return ((index % n) + n) % n; 27 | } 28 | static inline int mod_floor(int a, int n) { 29 | return ((a % n) + n) % n; 30 | } 31 | 32 | __attribute__((always_inline)) static inline uint32_t calculate_checksum(uint32_t const *p, size_t const size){ 33 | uint32_t checksum = 0; 34 | for (uint32_t i = 0; i < (size/sizeof(uint32_t))-1; i++){ 35 | checksum ^= *p; 36 | p++; 37 | } 38 | return checksum; 39 | } 40 | 41 | static inline void system_reset() { 42 | __NVIC_SystemReset(); 43 | } 44 | 45 | static inline void dump_bytes(size_t num, uint8_t bytes[num]) { 46 | printf(" "); 47 | for (size_t j = 0; j < 16; ++j) { 48 | printf("%02hhx", j); 49 | if (j < 15) 50 | printf(" "); 51 | else { 52 | printf("\n"); 53 | } 54 | } 55 | for (size_t i = 0; i < num; i += 16) { 56 | printf("%04x ", i); 57 | for (size_t j = 0; j < 16 && i + j < num; ++j) { 58 | printf("%02hhx", bytes[i + j]); 59 | if (j < 15) 60 | printf(" "); 61 | else { 62 | printf("\n"); 63 | } 64 | } 65 | } 66 | printf("\n"); 67 | fflush(stdout); 68 | } 69 | 70 | #endif 71 | /* [] END OF FILE */ 72 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/mbed-os/LICENSE.md: -------------------------------------------------------------------------------- 1 | Unless specifically indicated otherwise in a file, files are licensed under the Apache 2.0 license, 2 | as can be found in: LICENSE-apache-2.0.txt 3 | 4 | Folders containing files under different permissive license than Apache 2.0 are listed below. Each folder should contain its own README file with license specified for its files. The original license text is included in those source files. 5 | 6 | - [cmsis](cmsis) - MIT 7 | - [connectivity/FEATURE_BLE](connectivity/FEATURE_BLE) - BSD-3-Clause, MIT 8 | - [connectivity/drivers/802.15.4_RF/mcr20a-rf-driver](connectivity/drivers/802.15.4_RF/mcr20a-rf-driver) - BSD-3-Clause 9 | - [connectivity/drivers/ble/FEATURE_BLE](connectivity/drivers/ble/FEATURE_BLE) - MIT, PBL, BSD-3-Clause 10 | - [connectivity/drivers/emac](connectivity/drivers/emac) - BSD-3-Clause 11 | - [connectivity/drivers/lora](connectivity/drivers/lora) - BSD-3-Clause 12 | - [connectivity/drivers/mbedtls/FEATURE_CRYPTOCELL310](connectivity/drivers/mbedtls/FEATURE_CRYPTOCELL310) - ARM Object Code and Header Files 13 | - [connectivity/libraries/ppp](connectivity/libraries/ppp) - BSD-3-Clause, BSD-4-Clause 14 | - [connectivity/lorawan](connectivity/lorawan) - BSD-3-Clause 15 | - [connectivity/lwipstack](connectivity/lwipstack) - BSD-2-Clause, BSD-3-Clause, MIT 16 | - [connectivity/nanostack](connectivity/nanostack) - BSD-3-Clause 17 | - [drivers](drivers) - MIT 18 | - [features](features) - MIT 19 | - [platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/services/attestation/qcbor](platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/services/attestation/qcbor) - BSD-3-Clause 20 | - [platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/services/attestation](platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/services/attestation) - BSD-3-Clause 21 | - [platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM](platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM) - BSD-3-Clause 22 | - [rtos](rtos) - MIT 23 | - [storage/blockdevice/include/blockdevice](storage/blockdevice/include/blockdevice) - BSD-2-Clause, BSD-3-Clause, MIT 24 | - [storage/filesystem/fat/ChaN](storage/filesystem/fat/ChaN) - BSD-2-Clause, [Copyright ChaN](http://www.elm-chan.org/fsw/ff/doc/appnote.html) 25 | - [storage/filesystem/fat](storage/filesystem/fat) - MIT 26 | - [storage/filesystem/littlefs](storage/filesystem/littlefs)- BSD-3-Clause, MIT 27 | - [storage/filesystem/littlefsv2](storage/filesystem/littlefsv2)- BSD-3-Clause, MIT 28 | - [targets](targets) - ADI BSD, AMD Historical, BSD-2-Clause, BSD-3-Clause, Beer-Ware, MIT, MPLv2.0, SGI-B-1.1, XFree86, ZLIB 29 | 30 | The Python modules used by Mbed tools are used under the following licenses: 31 | 32 | - [beautifulsoup4](https://pypi.org/project/beautifulsoup4) - MIT 33 | - [cbor](https://pypi.org/project/cbor) - Apache-2.0 34 | - [click](https://pypi.org/project/click) - BSD-3-Clause 35 | - [cmsis-pack-manager](https://pypi.org/project/cmsis-pack-manager) - Apache-2.0 36 | - [colorama](https://pypi.org/project/colorama) - BSD-3-Clause 37 | - [cryptography](https://pypi.org/project/cryptography) - BSD, Apache-2.0 38 | - [cysecuretools](https://pypi.org/project/cysecuretools/) - Apache-2.0 39 | - [future](https://pypi.org/project/future) - MIT 40 | - [hidapi](https://pypi.org/project/hidapi) - BSD-style 41 | - [icetea](https://pypi.org/project/icetea) - Apache-2.0 42 | - [idna](https://pypi.org/project/idna) - BSD-3-Clause 43 | - [intelhex](https://pypi.org/project/intelhex) - BSD 44 | - [Jinja2](https://pypi.org/project/Jinja2) - BSD-3-Clause 45 | - [jsonschema](https://pypi.org/project/jsonschema) - MIT 46 | - [junit-xml](https://pypi.org/project/junit-xml) - MIT 47 | - [mbed-greentea](https://pypi.org/project/mbed-greentea) - Apache-2.0 48 | - [mbed-host-tests](https://pypi.org/project/mbed-host-tests) - Apache-2.0 49 | - [mbed-ls](https://pypi.org/project/mbed-ls) - Apache-2.0 50 | - [prettytable](https://pypi.org/project/prettytable) - BSD-3-Clause 51 | - [psutil](https://pypi.org/project/psutil) - BSD 52 | - [pycryptodome](https://pypi.org/project/pycryptodome) - BSD-2-Clause 53 | - [pyelftools](https://pypi.org/project/pyelftools) - Public Domain 54 | - [pyserial](https://pypi.org/project/pyserial) - BSD-3-Clause 55 | - [pyusb](https://pypi.org/project/pyusb) - Apache-2.0 56 | - [pywin32](https://pypi.org/project/pywin32) - PSF 57 | - [pyyaml](https://pypi.org/project/pyyaml) - MIT 58 | - [requests](https://pypi.org/project/requests) - Apache-2.0 59 | - [secure](https://pypi.org/project/secure) - MIT 60 | - [six](https://pypi.org/project/six) - MIT 61 | - [urllib3](https://pypi.org/project/urllib3) - MIT 62 | - [wmi](https://pypi.org/project/WMI) - MIT 63 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/mbed-os/README.md: -------------------------------------------------------------------------------- 1 | [![Mbed OS][mbed-os-logo]][mbed-os-link] 2 | 3 | [![Build status master][mbed-master-svg]][mbed-master] 4 | [![Tools coverage status][mbed-coveralls-tools-svg]][mbed-coveralls-tools] 5 | 6 | [mbed-os-logo]: logo.png 7 | [mbed-os-link]: https://www.mbed.com/en/platform/mbed-os/ 8 | [mbed-master]: https://github.com/ARMmbed/mbed-os/actions/workflows/basic_checks.yml 9 | [mbed-master-svg]: https://github.com/ARMmbed/mbed-os/actions/workflows/basic_checks.yml/badge.svg 10 | [mbed-coveralls-tools]: https://coveralls.io/github/ARMmbed/mbed-os?branch=master 11 | [mbed-coveralls-tools-svg]: https://coveralls.io/repos/github/ARMmbed/mbed-os/badge.svg?branch=master 12 | 13 | Arm Mbed OS is an open source embedded operating system designed specifically for the "things" in the Internet of Things. It includes all the features you need to develop a connected product based on an Arm Cortex-M microcontroller, including security, connectivity, an RTOS and drivers for sensors and I/O devices. 14 | 15 | Mbed OS provides a platform that includes: 16 | 17 | - Security foundations. 18 | - Cloud management services. 19 | - Drivers for sensors, I/O devices and connectivity. 20 | 21 | ## Release notes 22 | The [release notes](https://os.mbed.com/releases) detail the current release. You can also find information about previous versions. 23 | 24 | ## License and contributions 25 | 26 | The software is provided under the [Apache-2.0 license](LICENSE-apache-2.0.txt). Contributions to this project are accepted under the same license. Please see [contributing.md](CONTRIBUTING.md) for more information. 27 | 28 | This project contains code from other projects. The original license text is included in those source files. They must comply with our [license guide](https://os.mbed.com/docs/mbed-os/latest/contributing/license.html). 29 | 30 | Folders containing files under different permissive license than Apache 2.0 are listed in the [LICENSE](LICENSE.md) file. 31 | 32 | ## Getting started for developers 33 | 34 | We have a [developer website](https://os.mbed.com) for asking questions, engaging with others, finding information on boards and components, using an online IDE and compiler, reading the documentation and learning about what's new and what's coming next in Mbed OS. 35 | 36 | ## Getting started for contributors 37 | 38 | We also have a [contributing and publishing guide](https://os.mbed.com/contributing/) that covers licensing, contributor agreements and style guidelines. 39 | 40 | ## Documentation 41 | 42 | For more information about Mbed OS, please see [our published documentation](https://os.mbed.com/docs/latest). It includes Doxygen for our APIs, step-by-step tutorials, porting information and background reference materials about our architecture and tools. 43 | 44 | To contribute to this documentation, please see the [mbed-os-5-docs repository](https://github.com/ARMmbed/mbed-os-5-docs). 45 | 46 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/sd_driver/SDIO/rp2040_sdio.h: -------------------------------------------------------------------------------- 1 | // SD card access using SDIO for RP2040 platform. 2 | // This module contains the low-level SDIO bus implementation using 3 | // the PIO peripheral. The high-level commands are in sd_card_sdio.cpp. 4 | 5 | #pragma once 6 | #include 7 | // 8 | #include "sd_card.h" 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | typedef 15 | enum sdio_status_t { 16 | SDIO_OK = 0, 17 | SDIO_BUSY = 1, 18 | SDIO_ERR_RESPONSE_TIMEOUT = 2, // Timed out waiting for response from card 19 | SDIO_ERR_RESPONSE_CRC = 3, // Response CRC is wrong 20 | SDIO_ERR_RESPONSE_CODE = 4, // Response command code does not match what was sent 21 | SDIO_ERR_DATA_TIMEOUT = 5, // Timed out waiting for data block 22 | SDIO_ERR_DATA_CRC = 6, // CRC for data packet is wrong 23 | SDIO_ERR_WRITE_CRC = 7, // Card reports bad CRC for write 24 | SDIO_ERR_WRITE_FAIL = 8, // Card reports write failure 25 | } sdio_status_t; 26 | 27 | #define SDIO_BLOCK_SIZE 512 28 | #define SDIO_WORDS_PER_BLOCK 128 29 | 30 | // Execute a command that has 48-bit reply (response types R1, R6, R7) 31 | // If response is NULL, does not wait for reply. 32 | sdio_status_t rp2040_sdio_command_R1(sd_card_t *sd_card_p, uint8_t command, uint32_t arg, uint32_t *response); 33 | 34 | // Execute a command that has 136-bit reply (response type R2) 35 | // Response buffer should have space for 16 bytes (the 128 bit payload) 36 | sdio_status_t rp2040_sdio_command_R2(sd_card_t *sd_card_p, uint8_t command, uint32_t arg, uint8_t *response); 37 | 38 | // Execute a command that has 48-bit reply but without CRC (response R3) 39 | sdio_status_t rp2040_sdio_command_R3(sd_card_t *sd_card_p, uint8_t command, uint32_t arg, uint32_t *response); 40 | 41 | // Start transferring data from SD card to memory buffer 42 | // Transfer block size is always 512 bytes. 43 | sdio_status_t rp2040_sdio_rx_start(sd_card_t *sd_card_p, uint8_t *buffer, uint32_t num_blocks); 44 | 45 | // Check if reception is complete 46 | // Returns SDIO_BUSY while transferring, SDIO_OK when done and error on failure. 47 | sdio_status_t rp2040_sdio_rx_poll(sd_card_t *sd_card_p, uint32_t *bytes_complete /* = nullptr */); 48 | 49 | // Start transferring data from memory to SD card 50 | sdio_status_t rp2040_sdio_tx_start(sd_card_t *sd_card_p, const uint8_t *buffer, uint32_t num_blocks); 51 | 52 | // Check if transmission is complete 53 | sdio_status_t rp2040_sdio_tx_poll(sd_card_t *sd_card_p, uint32_t *bytes_complete /* = nullptr */); 54 | 55 | // Force everything to idle state 56 | sdio_status_t rp2040_sdio_stop(); 57 | 58 | // (Re)initialize the SDIO interface 59 | void rp2040_sdio_init(sd_card_t *sd_card_p, int clock_divider /* = 1 */); 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/sd_driver/SDIO/rp2040_sdio.pio.h: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------- // 2 | // This file is autogenerated by pioasm; do not edit! // 3 | // -------------------------------------------------- // 4 | 5 | #pragma once 6 | 7 | #if !PICO_NO_HARDWARE 8 | #include "hardware/pio.h" 9 | #endif 10 | 11 | #define SDIO_CLK_PIN_D0_OFFSET 30 12 | 13 | // ------------ // 14 | // sdio_cmd_clk // 15 | // ------------ // 16 | 17 | #define sdio_cmd_clk_wrap_target 0 18 | #define sdio_cmd_clk_wrap 17 19 | 20 | static const uint16_t sdio_cmd_clk_program_instructions[] = { 21 | // .wrap_target 22 | 0xb1e3, // 0: mov osr, null side 1 [1] 23 | 0xa14d, // 1: mov y, !status side 0 [1] 24 | 0x1161, // 2: jmp !y, 1 side 1 [1] 25 | 0x6160, // 3: out null, 32 side 0 [1] 26 | 0x7128, // 4: out x, 8 side 1 [1] 27 | 0xe101, // 5: set pins, 1 side 0 [1] 28 | 0xf181, // 6: set pindirs, 1 side 1 [1] 29 | 0x6101, // 7: out pins, 1 side 0 [1] 30 | 0x1147, // 8: jmp x--, 7 side 1 [1] 31 | 0xe180, // 9: set pindirs, 0 side 0 [1] 32 | 0x7128, // 10: out x, 8 side 1 [1] 33 | 0xa142, // 11: nop side 0 [1] 34 | 0x1131, // 12: jmp !x, 17 side 1 [1] 35 | 0xa142, // 13: nop side 0 [1] 36 | 0x11cd, // 14: jmp pin, 13 side 1 [1] 37 | 0x4101, // 15: in pins, 1 side 0 [1] 38 | 0x114f, // 16: jmp x--, 15 side 1 [1] 39 | 0x8120, // 17: push block side 0 [1] 40 | // .wrap 41 | }; 42 | 43 | #if !PICO_NO_HARDWARE 44 | static const struct pio_program sdio_cmd_clk_program = { 45 | .instructions = sdio_cmd_clk_program_instructions, 46 | .length = 18, 47 | .origin = -1, 48 | }; 49 | 50 | static inline pio_sm_config sdio_cmd_clk_program_get_default_config(uint offset) { 51 | pio_sm_config c = pio_get_default_sm_config(); 52 | sm_config_set_wrap(&c, offset + sdio_cmd_clk_wrap_target, offset + sdio_cmd_clk_wrap); 53 | sm_config_set_sideset(&c, 1, false, false); 54 | return c; 55 | } 56 | #endif 57 | 58 | // ------------ // 59 | // sdio_data_rx // 60 | // ------------ // 61 | 62 | #define sdio_data_rx_wrap_target 0 63 | #define sdio_data_rx_wrap 4 64 | 65 | static const uint16_t sdio_data_rx_program_instructions[] = { 66 | // .wrap_target 67 | 0xa022, // 0: mov x, y 68 | 0x2020, // 1: wait 0 pin, 0 69 | 0x23be, // 2: wait 1 pin, 30 [3] 70 | 0x4204, // 3: in pins, 4 [2] 71 | 0x0043, // 4: jmp x--, 3 72 | // .wrap 73 | }; 74 | 75 | #if !PICO_NO_HARDWARE 76 | static const struct pio_program sdio_data_rx_program = { 77 | .instructions = sdio_data_rx_program_instructions, 78 | .length = 5, 79 | .origin = -1, 80 | }; 81 | 82 | static inline pio_sm_config sdio_data_rx_program_get_default_config(uint offset) { 83 | pio_sm_config c = pio_get_default_sm_config(); 84 | sm_config_set_wrap(&c, offset + sdio_data_rx_wrap_target, offset + sdio_data_rx_wrap); 85 | return c; 86 | } 87 | #endif 88 | 89 | // ------------ // 90 | // sdio_data_tx // 91 | // ------------ // 92 | 93 | #define sdio_data_tx_wrap_target 5 94 | #define sdio_data_tx_wrap 8 95 | 96 | static const uint16_t sdio_data_tx_program_instructions[] = { 97 | 0x203e, // 0: wait 0 pin, 30 98 | 0x24be, // 1: wait 1 pin, 30 [4] 99 | 0x6104, // 2: out pins, 4 [1] 100 | 0x0142, // 3: jmp x--, 2 [1] 101 | 0xe180, // 4: set pindirs, 0 [1] 102 | // .wrap_target 103 | 0x4101, // 5: in pins, 1 [1] 104 | 0x0185, // 6: jmp y--, 5 [1] 105 | 0x21a0, // 7: wait 1 pin, 0 [1] 106 | 0x8120, // 8: push block [1] 107 | // .wrap 108 | }; 109 | 110 | #if !PICO_NO_HARDWARE 111 | static const struct pio_program sdio_data_tx_program = { 112 | .instructions = sdio_data_tx_program_instructions, 113 | .length = 9, 114 | .origin = -1, 115 | }; 116 | 117 | static inline pio_sm_config sdio_data_tx_program_get_default_config(uint offset) { 118 | pio_sm_config c = pio_get_default_sm_config(); 119 | sm_config_set_wrap(&c, offset + sdio_data_tx_wrap_target, offset + sdio_data_tx_wrap); 120 | return c; 121 | } 122 | #endif 123 | 124 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/sd_driver/SPI/crc.h: -------------------------------------------------------------------------------- 1 | /* crc.h 2 | Copyright 2021 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | /* Derived from: 15 | * SD/MMC File System Library 16 | * Copyright (c) 2016 Neil Thiessen 17 | * 18 | * Licensed under the Apache License, Version 2.0 (the "License"); 19 | * you may not use this file except in compliance with the License. 20 | * You may obtain a copy of the License at 21 | * 22 | * http://www.apache.org/licenses/LICENSE-2.0 23 | * 24 | * Unless required by applicable law or agreed to in writing, software 25 | * distributed under the License is distributed on an "AS IS" BASIS, 26 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 27 | * See the License for the specific language governing permissions and 28 | * limitations under the License. 29 | */ 30 | 31 | #ifndef SD_CRC_H 32 | #define SD_CRC_H 33 | 34 | #include 35 | 36 | char crc7(const char* data, int length); 37 | unsigned short crc16(const char* data, int length); 38 | void update_crc16(unsigned short *pCrc16, const char data[], size_t length); 39 | 40 | #endif 41 | 42 | /* [] END OF FILE */ 43 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/sd_driver/SPI/sd_card_constants.h: -------------------------------------------------------------------------------- 1 | /* sd_card_constants.h 2 | Copyright 2021 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | 15 | #pragma once 16 | 17 | 18 | // Only HC block size is supported. Making this a static constant reduces code 19 | // size. 20 | #define BLOCK_SIZE_HC 512 /*!< Block size supported for SD card is 512 bytes */ 21 | static const uint32_t _block_size = BLOCK_SIZE_HC; 22 | 23 | #define SD_BLOCK_DEVICE_ERROR_NONE 0 24 | #define SD_BLOCK_DEVICE_ERROR_WOULD_BLOCK -5001 /*!< operation would block */ 25 | #define SD_BLOCK_DEVICE_ERROR_UNSUPPORTED -5002 /*!< unsupported operation */ 26 | #define SD_BLOCK_DEVICE_ERROR_PARAMETER -5003 /*!< invalid parameter */ 27 | #define SD_BLOCK_DEVICE_ERROR_NO_INIT -5004 /*!< uninitialized */ 28 | #define SD_BLOCK_DEVICE_ERROR_NO_DEVICE -5005 /*!< device is missing or not connected */ 29 | #define SD_BLOCK_DEVICE_ERROR_WRITE_PROTECTED -5006 /*!< write protected */ 30 | #define SD_BLOCK_DEVICE_ERROR_UNUSABLE -5007 /*!< unusable card */ 31 | #define SD_BLOCK_DEVICE_ERROR_NO_RESPONSE -5008 /*!< No response from device */ 32 | #define SD_BLOCK_DEVICE_ERROR_CRC -5009 /*!< CRC error */ 33 | #define SD_BLOCK_DEVICE_ERROR_ERASE -5010 /*!< Erase error: reset/sequence */ 34 | #define SD_BLOCK_DEVICE_ERROR_WRITE -5011 /*!< SPI Write error: !SPI_DATA_ACCEPTED */ 35 | 36 | /** Represents the different SD/MMC card types */ 37 | // Types 38 | #define SDCARD_NONE 0 /**< No card is present */ 39 | #define SDCARD_V1 1 /**< v1.x Standard Capacity */ 40 | #define SDCARD_V2 2 /**< v2.x Standard capacity SD card */ 41 | #define SDCARD_V2HC 3 /**< v2.x High capacity SD card */ 42 | #define CARD_UNKNOWN 4 /**< Unknown or unsupported card */ 43 | 44 | // Supported SD Card Commands 45 | typedef enum { 46 | CMD_NOT_SUPPORTED = -1, /**< Command not supported error */ 47 | CMD0_GO_IDLE_STATE = 0, /**< Resets the SD Memory Card */ 48 | CMD1_SEND_OP_COND = 1, /**< Sends host capacity support */ 49 | CMD6_SWITCH_FUNC = 6, /**< Check and Switches card function */ 50 | CMD8_SEND_IF_COND = 8, /**< Supply voltage info */ 51 | CMD9_SEND_CSD = 9, /**< Provides Card Specific data */ 52 | CMD10_SEND_CID = 10, /**< Provides Card Identification */ 53 | CMD12_STOP_TRANSMISSION = 12, /**< Forces the card to stop transmission */ 54 | CMD13_SEND_STATUS = 13, /**< Card responds with status */ 55 | CMD16_SET_BLOCKLEN = 16, /**< Length for SC card is set */ 56 | CMD17_READ_SINGLE_BLOCK = 17, /**< Read single block of data */ 57 | CMD18_READ_MULTIPLE_BLOCK = 18, /**< Card transfers data blocks to host 58 | until interrupted by a STOP_TRANSMISSION command */ 59 | CMD24_WRITE_BLOCK = 24, /**< Write single block of data */ 60 | CMD25_WRITE_MULTIPLE_BLOCK = 25, /**< Continuously writes blocks of data 61 | until 'Stop Tran' token is sent */ 62 | CMD27_PROGRAM_CSD = 27, /**< Programming bits of CSD */ 63 | CMD32_ERASE_WR_BLK_START_ADDR = 32, /**< Sets the address of the first write 64 | block to be erased. */ 65 | CMD33_ERASE_WR_BLK_END_ADDR = 33, /**< Sets the address of the last write 66 | block of the continuous range to be erased.*/ 67 | CMD38_ERASE = 38, /**< Erases all previously selected write blocks */ 68 | CMD55_APP_CMD = 55, /**< Extend to Applications specific commands */ 69 | CMD56_GEN_CMD = 56, /**< General Purpose Command */ 70 | CMD58_READ_OCR = 58, /**< Read OCR register of card */ 71 | CMD59_CRC_ON_OFF = 59, /**< Turns the CRC option on or off*/ 72 | // App Commands 73 | ACMD6_SET_BUS_WIDTH = 6, 74 | ACMD13_SD_STATUS = 13, 75 | ACMD22_SEND_NUM_WR_BLOCKS = 22, 76 | ACMD23_SET_WR_BLK_ERASE_COUNT = 23, 77 | ACMD41_SD_SEND_OP_COND = 41, 78 | ACMD42_SET_CLR_CARD_DETECT = 42, 79 | ACMD51_SEND_SCR = 51, 80 | } cmdSupported; 81 | 82 | ///* Disk Status Bits (DSTATUS) */ 83 | // See diskio.h. 84 | //enum { 85 | // STA_NOINIT = 0x01, /* Drive not initialized */ 86 | // STA_NODISK = 0x02, /* No medium in the drive */ 87 | // STA_PROTECT = 0x04 /* Write protected */ 88 | //}; 89 | 90 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/sd_driver/SPI/sd_card_spi.h: -------------------------------------------------------------------------------- 1 | /* sd_card_spi.h 2 | Copyright 2021 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | 15 | #pragma once 16 | 17 | void sd_spi_ctor(sd_card_t *sd_card_p); // Constructor for sd_card_t 18 | bool sd_spi_readCID(sd_card_t *sd_card_p, cid_t* cid); 19 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/sd_driver/SPI/sd_spi.h: -------------------------------------------------------------------------------- 1 | /* sd_spi.h 2 | Copyright 2021 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | 15 | #ifndef _SD_SPI_H_ 16 | #define _SD_SPI_H_ 17 | 18 | #include 19 | #include "sd_card.h" 20 | 21 | /* Transfer tx to SPI while receiving SPI to rx. 22 | tx or rx can be NULL if not important. */ 23 | bool sd_spi_transfer(sd_card_t *sd_card_p, const uint8_t *tx, uint8_t *rx, size_t length); 24 | uint8_t sd_spi_write(sd_card_t *sd_card_p, const uint8_t value); 25 | void sd_spi_deselect_pulse(sd_card_t *sd_card_p); 26 | void sd_spi_acquire(sd_card_t *sd_card_p); 27 | void sd_spi_release(sd_card_t *sd_card_p); 28 | void sd_spi_go_low_frequency(sd_card_t *this); 29 | void sd_spi_go_high_frequency(sd_card_t *this); 30 | 31 | /* 32 | After power up, the host starts the clock and sends the initializing sequence on the CMD line. 33 | This sequence is a contiguous stream of logical ‘1’s. The sequence length is the maximum of 1msec, 34 | 74 clocks or the supply-ramp-uptime; the additional 10 clocks 35 | (over the 64 clocks after what the card should be ready for communication) is 36 | provided to eliminate power-up synchronization problems. 37 | */ 38 | void sd_spi_send_initializing_sequence(sd_card_t * sd_card_p); 39 | 40 | #endif 41 | 42 | /* [] END OF FILE */ 43 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/sd_driver/SPI/spi.h: -------------------------------------------------------------------------------- 1 | /* spi.h 2 | Copyright 2021 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | 15 | #pragma once 16 | 17 | #include 18 | // 19 | // Pico includes 20 | #include "hardware/dma.h" 21 | #include "hardware/gpio.h" 22 | #include "hardware/irq.h" 23 | #include "hardware/spi.h" 24 | #include "pico/mutex.h" 25 | #include "pico/sem.h" 26 | #include "pico/types.h" 27 | 28 | #define SPI_FILL_CHAR (0xFF) 29 | 30 | // "Class" representing SPIs 31 | typedef struct { 32 | // SPI HW 33 | spi_inst_t *hw_inst; 34 | uint miso_gpio; // SPI MISO GPIO number (not pin number) 35 | uint mosi_gpio; 36 | uint sck_gpio; 37 | uint baud_rate; 38 | uint DMA_IRQ_num; // DMA_IRQ_0 or DMA_IRQ_1 39 | 40 | // Drive strength levels for GPIO outputs. 41 | // enum gpio_drive_strength { GPIO_DRIVE_STRENGTH_2MA = 0, GPIO_DRIVE_STRENGTH_4MA = 1, GPIO_DRIVE_STRENGTH_8MA = 2, 42 | // GPIO_DRIVE_STRENGTH_12MA = 3 } 43 | bool set_drive_strength; 44 | enum gpio_drive_strength mosi_gpio_drive_strength; 45 | enum gpio_drive_strength sck_gpio_drive_strength; 46 | 47 | /* The following fields are not part of the configuration. They are dynamically assigned. */ 48 | uint tx_dma; 49 | uint rx_dma; 50 | dma_channel_config tx_dma_cfg; 51 | dma_channel_config rx_dma_cfg; 52 | bool initialized; 53 | semaphore_t sem; 54 | mutex_t mutex; 55 | } spi_t; 56 | 57 | #ifdef __cplusplus 58 | extern "C" { 59 | #endif 60 | 61 | // // SPI DMA interrupts 62 | // void __not_in_flash_func(spi_irq_handler)(); 63 | 64 | bool __not_in_flash_func(spi_transfer)(spi_t *pSPI, const uint8_t *tx, uint8_t *rx, size_t length); 65 | void spi_lock(spi_t *pSPI); 66 | void spi_unlock(spi_t *pSPI); 67 | bool my_spi_init(spi_t *pSPI); 68 | void set_spi_dma_irq_channel(bool useChannel1, bool shared); 69 | 70 | #ifdef __cplusplus 71 | } 72 | #endif 73 | 74 | #ifndef NO_PICO_LED 75 | # define USE_LED 1 76 | #endif 77 | 78 | #if USE_LED 79 | # define LED_PIN 25 80 | # define LED_INIT() \ 81 | { \ 82 | gpio_init(LED_PIN); \ 83 | gpio_set_dir(LED_PIN, GPIO_OUT); \ 84 | } 85 | # define LED_ON() gpio_put(LED_PIN, 1) 86 | # define LED_OFF() gpio_put(LED_PIN, 0) 87 | #else 88 | # define LED_ON() 89 | # define LED_OFF() 90 | # define LED_INIT() 91 | #endif 92 | 93 | /* [] END OF FILE */ 94 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/sd_driver/hw_config.h: -------------------------------------------------------------------------------- 1 | /* hw_config.h 2 | Copyright 2021 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | #pragma once 15 | 16 | #include "ff.h" 17 | #include "sd_card.h" 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | size_t sd_get_num(); 24 | sd_card_t *sd_get_by_num(size_t num); 25 | 26 | size_t spi_get_num(); 27 | spi_t *spi_get_by_num(size_t num); 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif 32 | 33 | /* [] END OF FILE */ 34 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/sd_driver/sd_card.c: -------------------------------------------------------------------------------- 1 | /* sd_card.c 2 | Copyright 2021 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | 15 | /* Standard includes. */ 16 | #include 17 | #include 18 | // 19 | #include "pico/mutex.h" 20 | // 21 | #include "SDIO/SdioCard.h" 22 | #include "SPI/sd_card_spi.h" 23 | #include "hw_config.h" // Hardware Configuration of the SPI and SD Card "objects" 24 | #include "my_debug.h" 25 | // 26 | #include "sd_card.h" 27 | // 28 | #include "ff.h" /* Obtains integer types */ 29 | // 30 | #include "diskio.h" /* Declarations of disk functions */ // Needed for STA_NOINIT, ... 31 | 32 | #define TRACE_PRINTF(fmt, args...) 33 | // #define TRACE_PRINTF printf 34 | 35 | /* Return non-zero if the SD-card is present. */ 36 | bool sd_card_detect(sd_card_t *sd_card_p) { 37 | TRACE_PRINTF("> %s\r\n", __FUNCTION__); 38 | if (!sd_card_p->use_card_detect) { 39 | sd_card_p->m_Status &= ~STA_NODISK; 40 | return true; 41 | } 42 | /*!< Check GPIO to detect SD */ 43 | if (gpio_get(sd_card_p->card_detect_gpio) == sd_card_p->card_detected_true) { 44 | // The socket is now occupied 45 | sd_card_p->m_Status &= ~STA_NODISK; 46 | TRACE_PRINTF("SD card detected!\r\n"); 47 | return true; 48 | } else { 49 | // The socket is now empty 50 | sd_card_p->m_Status |= (STA_NODISK | STA_NOINIT); 51 | sd_card_p->card_type = SDCARD_NONE; 52 | printf("No SD card detected!\r\n"); 53 | return false; 54 | } 55 | } 56 | 57 | bool sd_init_driver() { 58 | static bool initialized; 59 | auto_init_mutex(initialized_mutex); 60 | mutex_enter_blocking(&initialized_mutex); 61 | if (!initialized) { 62 | for (size_t i = 0; i < sd_get_num(); ++i) { 63 | sd_card_t *sd_card_p = sd_get_by_num(i); 64 | switch (sd_card_p->type) { 65 | case SD_IF_SPI: 66 | sd_spi_ctor(sd_card_p); 67 | break; 68 | case SD_IF_SDIO: 69 | sd_sdio_ctor(sd_card_p); 70 | break; 71 | } // switch (sd_card_p->type) 72 | } // for 73 | for (size_t i = 0; i < spi_get_num(); ++i) { 74 | spi_t *spi_p = spi_get_by_num(i); 75 | if (!my_spi_init(spi_p)) { 76 | mutex_exit(&initialized_mutex); 77 | return false; 78 | } 79 | } 80 | initialized = true; 81 | } 82 | mutex_exit(&initialized_mutex); 83 | return true; 84 | } 85 | /* [] END OF FILE */ 86 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/sd_driver/sd_card.h: -------------------------------------------------------------------------------- 1 | /* sd_card.h 2 | Copyright 2021 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | 15 | // Note: The model used here is one FatFS per SD card. 16 | // Multiple partitions on a card are not supported. 17 | 18 | #pragma once 19 | 20 | #include 21 | // 22 | #include "hardware/gpio.h" 23 | #include 24 | #include "pico/mutex.h" 25 | // 26 | #include "ff.h" 27 | // 28 | #include "SPI/spi.h" 29 | #include "SPI/sd_card_constants.h" 30 | // 31 | #include "SdCardInfo.h" 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | typedef enum { 38 | SD_IF_SPI, 39 | SD_IF_SDIO 40 | } sd_if_t; 41 | 42 | typedef struct sd_spi_t { 43 | spi_t *spi; 44 | // Slave select is here instead of in spi_t because multiple SDs can share an SPI. 45 | uint ss_gpio; // Slave select for this SD card 46 | // Drive strength levels for GPIO outputs. 47 | // enum gpio_drive_strength { GPIO_DRIVE_STRENGTH_2MA = 0, GPIO_DRIVE_STRENGTH_4MA = 1, GPIO_DRIVE_STRENGTH_8MA = 2, 48 | // GPIO_DRIVE_STRENGTH_12MA = 3 } 49 | bool set_drive_strength; 50 | enum gpio_drive_strength ss_gpio_drive_strength; 51 | } sd_spi_t; 52 | 53 | typedef struct sd_sdio_t { 54 | // See sd_driver\SDIO\rp2040_sdio.pio for SDIO_CLK_PIN_D0_OFFSET 55 | uint CLK_gpio; // Must be (D0_gpio + SDIO_CLK_PIN_D0_OFFSET) % 32 56 | uint CMD_gpio; 57 | uint D0_gpio; // D0 58 | uint D1_gpio; // Must be D0 + 1 59 | uint D2_gpio; // Must be D0 + 2 60 | uint D3_gpio; // Must be D0 + 3 61 | PIO SDIO_PIO; // either pio0 or pio1 62 | uint DMA_IRQ_num; // DMA_IRQ_0 or DMA_IRQ_1 63 | 64 | /* The following fields are not part of the configuration. They are dynamically assigned. */ 65 | int SDIO_DMA_CH; 66 | int SDIO_DMA_CHB; 67 | int SDIO_CMD_SM; 68 | int SDIO_DATA_SM; 69 | } sd_sdio_t; 70 | 71 | typedef struct sd_card_t sd_card_t; 72 | 73 | // "Class" representing SD Cards 74 | struct sd_card_t { 75 | const char *pcName; 76 | sd_if_t type; 77 | union { 78 | sd_spi_t spi_if; 79 | sd_sdio_t sdio_if; 80 | }; 81 | bool use_card_detect; 82 | uint card_detect_gpio; // Card detect; ignored if !use_card_detect 83 | uint card_detected_true; // Varies with card socket; ignored if !use_card_detect 84 | 85 | /* The following fields are not part of the configuration. They are dynamically assigned. */ 86 | int m_Status; // Card status 87 | uint64_t sectors; // Assigned dynamically 88 | int card_type; // Assigned dynamically 89 | mutex_t mutex; 90 | FATFS fatfs; 91 | bool mounted; 92 | 93 | int (*init)(sd_card_t *sd_card_p); 94 | int (*write_blocks)(sd_card_t *sd_card_p, const uint8_t *buffer, 95 | uint64_t ulSectorNumber, uint32_t blockCnt); 96 | int (*read_blocks)(sd_card_t *sd_card_p, uint8_t *buffer, uint64_t ulSectorNumber, 97 | uint32_t ulSectorCount); 98 | uint64_t (*get_num_sectors)(sd_card_t *sd_card_p); 99 | bool (*sd_readCID)(sd_card_t *sd_card_p, cid_t *cid); 100 | }; 101 | bool sd_init_driver(); 102 | bool sd_card_detect(sd_card_t *sd_card_p); 103 | 104 | #ifdef __cplusplus 105 | } 106 | #endif 107 | 108 | /* [] END OF FILE */ 109 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/source/FatFsSd.cpp: -------------------------------------------------------------------------------- 1 | /* FatFsSd.cpp 2 | Copyright 2023 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | 15 | #include "FatFsSd.h" 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | using namespace FatFsNs; 22 | 23 | /* 24 | See FatFs - Generic FAT Filesystem Module, "Application Interface", 25 | http://elm-chan.org/fsw/ff/00index_e.html 26 | */ 27 | 28 | std::vector FatFs::Spis; 29 | std::vector FatFs::SdCards; 30 | 31 | /* Put a formatted string to the file */ 32 | int File::printf(const TCHAR* format, ...) { 33 | va_list arg; 34 | va_start(arg, format); 35 | char temp[64]; 36 | char* buffer = temp; 37 | size_t len = vsnprintf(temp, sizeof(temp), format, arg); 38 | va_end(arg); 39 | if (len > sizeof(temp) - 1) { 40 | buffer = new char[len + 1]; 41 | if (!buffer) { 42 | return 0; 43 | } 44 | va_start(arg, format); 45 | int vrc = vsnprintf(buffer, len + 1, format, arg); 46 | // Notice that only when this returned value is non-negative and less than n, 47 | // the string has been completely written. 48 | assert(vrc >= 0 && vrc < len + 1); 49 | va_end(arg); 50 | } 51 | UINT bw; 52 | FRESULT fr = f_write(&fil, buffer, len, &bw); 53 | int rc = bw; 54 | if (FR_OK != fr) { 55 | rc = -1; 56 | } 57 | if (buffer != temp) { 58 | delete[] buffer; 59 | } 60 | return rc; 61 | } 62 | 63 | bool FatFs::begin() { 64 | if (!sd_init_driver()) 65 | return false; 66 | for (size_t i = 0; i < sd_get_num(); ++i) { 67 | sd_card_t* sd_card_p = sd_get_by_num(i); 68 | if (!sd_card_p) return false; 69 | // See http://elm-chan.org/fsw/ff/doc/dstat.html 70 | int dstatus = sd_card_p->init(sd_card_p); 71 | if (dstatus & STA_NOINIT) return false; 72 | } 73 | return true; 74 | } 75 | 76 | size_t __attribute__((weak)) spi_get_num() { 77 | return FatFs::Spi_get_num(); 78 | } 79 | spi_t __attribute__((weak)) * spi_get_by_num(size_t num) { 80 | return &FatFs::Spi_get_by_num(num)->m_spi; 81 | } 82 | size_t __attribute__((weak)) sd_get_num() { 83 | return FatFs::SdCard_get_num(); 84 | } 85 | sd_card_t __attribute__((weak)) * sd_get_by_num(size_t num) { 86 | return &(FatFs::SdCard_get_by_num(num)->m_sd_card); 87 | } 88 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/source/f_util.c: -------------------------------------------------------------------------------- 1 | /* f_util.c 2 | Copyright 2021 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | #include "ff.h" 15 | 16 | const char *FRESULT_str(FRESULT i) { 17 | switch (i) { 18 | case FR_OK: 19 | return "Succeeded"; 20 | case FR_DISK_ERR: 21 | return "A hard error occurred in the low level disk I/O layer"; 22 | case FR_INT_ERR: 23 | return "Assertion failed"; 24 | case FR_NOT_READY: 25 | return "The physical drive cannot work"; 26 | case FR_NO_FILE: 27 | return "Could not find the file"; 28 | case FR_NO_PATH: 29 | return "Could not find the path"; 30 | case FR_INVALID_NAME: 31 | return "The path name format is invalid"; 32 | case FR_DENIED: 33 | return "Access denied due to prohibited access or directory full"; 34 | case FR_EXIST: 35 | return "Access denied due to prohibited access (exists)"; 36 | case FR_INVALID_OBJECT: 37 | return "The file/directory object is invalid"; 38 | case FR_WRITE_PROTECTED: 39 | return "The physical drive is write protected"; 40 | case FR_INVALID_DRIVE: 41 | return "The logical drive number is invalid"; 42 | case FR_NOT_ENABLED: 43 | return "The volume has no work area (mount)"; 44 | case FR_NO_FILESYSTEM: 45 | return "There is no valid FAT volume"; 46 | case FR_MKFS_ABORTED: 47 | return "The f_mkfs() aborted due to any problem"; 48 | case FR_TIMEOUT: 49 | return "Could not get a grant to access the volume within defined " 50 | "period"; 51 | case FR_LOCKED: 52 | return "The operation is rejected according to the file sharing " 53 | "policy"; 54 | case FR_NOT_ENOUGH_CORE: 55 | return "LFN working buffer could not be allocated"; 56 | case FR_TOO_MANY_OPEN_FILES: 57 | return "Number of open files > FF_FS_LOCK"; 58 | case FR_INVALID_PARAMETER: 59 | return "Given parameter is invalid"; 60 | default: 61 | return "Unknown"; 62 | } 63 | } 64 | 65 | FRESULT delete_node ( 66 | TCHAR* path, /* Path name buffer with the sub-directory to delete */ 67 | UINT sz_buff, /* Size of path name buffer (items) */ 68 | FILINFO* fno /* Name read buffer */ 69 | ) 70 | { 71 | UINT i, j; 72 | FRESULT fr; 73 | DIR dir; 74 | 75 | 76 | fr = f_opendir(&dir, path); /* Open the sub-directory to make it empty */ 77 | if (fr != FR_OK) return fr; 78 | 79 | for (i = 0; path[i]; i++) ; /* Get current path length */ 80 | path[i++] = '/'; 81 | 82 | for (;;) { 83 | fr = f_readdir(&dir, fno); /* Get a directory item */ 84 | if (fr != FR_OK || !fno->fname[0]) break; /* End of directory? */ 85 | j = 0; 86 | do { /* Make a path name */ 87 | if (i + j >= sz_buff) { /* Buffer over flow? */ 88 | fr = 100; break; /* Fails with 100 when buffer overflow */ 89 | } 90 | path[i + j] = fno->fname[j]; 91 | } while (fno->fname[j++]); 92 | if (fno->fattrib & AM_DIR) { /* Item is a sub-directory */ 93 | fr = delete_node(path, sz_buff, fno); 94 | } else { /* Item is a file */ 95 | fr = f_unlink(path); 96 | } 97 | if (fr != FR_OK) break; 98 | } 99 | 100 | path[--i] = 0; /* Restore the path name */ 101 | f_closedir(&dir); 102 | 103 | if (fr == FR_OK) fr = f_unlink(path); /* Delete the empty sub-directory */ 104 | return fr; 105 | } 106 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/source/my_debug.c: -------------------------------------------------------------------------------- 1 | /* my_debug.c 2 | Copyright 2021 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | #include 15 | #include "my_debug.h" 16 | 17 | #ifdef USE_PRINTF 18 | # include 19 | void my_printf(const char *pcFormat, ...) { 20 | char pcBuffer[256] = {0}; 21 | va_list xArgs; 22 | va_start(xArgs, pcFormat); 23 | vsnprintf(pcBuffer, sizeof(pcBuffer), pcFormat, xArgs); 24 | va_end(xArgs); 25 | printf("%s", pcBuffer); 26 | fflush(stdout); 27 | } 28 | #else 29 | # define my_printf(...) // Do nothing 30 | # define printf(...) // Do nothing 31 | # define puts(...) 32 | # define fflush(...) 33 | #endif 34 | 35 | 36 | void my_assert_func(const char *file, int line, const char *func, 37 | const char *pred) { 38 | printf("assertion \"%s\" failed: file \"%s\", line %d, function: %s\n", 39 | pred, file, line, func); 40 | fflush(stdout); 41 | __asm volatile("cpsid i" : : : "memory"); /* Disable global interrupts. */ 42 | while (1) { 43 | __asm("bkpt #0"); 44 | }; // Stop in GUI as if at a breakpoint (if debugging, otherwise loop 45 | // forever) 46 | } 47 | -------------------------------------------------------------------------------- /no-OS-FatFS-SD-SPI-RPi-Pico/src/source/rtc.c: -------------------------------------------------------------------------------- 1 | /* rtc.c 2 | Copyright 2021 Carl John Kugler III 3 | 4 | Licensed under the Apache License, Version 2.0 (the License); you may not use 5 | this file except in compliance with the License. You may obtain a copy of the 6 | License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | */ 14 | #include 15 | // 16 | #include "hardware/rtc.h" 17 | #include "pico/stdio.h" 18 | #include "pico/stdlib.h" 19 | #include "pico/util/datetime.h" 20 | // 21 | #include "ff.h" 22 | #include "util.h" // calculate_checksum 23 | // 24 | #include "rtc.h" 25 | 26 | static time_t epochtime; 27 | 28 | // Make an attempt to save a recent time stamp across reset: 29 | typedef struct rtc_save { 30 | uint32_t signature; 31 | datetime_t datetime; 32 | uint32_t checksum; // last, not included in checksum 33 | } rtc_save_t; 34 | static rtc_save_t rtc_save __attribute__((section(".uninitialized_data"))); 35 | 36 | static void update_epochtime() { 37 | bool rc = rtc_get_datetime(&rtc_save.datetime); 38 | if (rc) { 39 | rtc_save.signature = 0xBABEBABE; 40 | struct tm timeinfo = { 41 | .tm_sec = rtc_save.datetime 42 | .sec, /* Seconds. [0-60] (1 leap second) */ 43 | .tm_min = rtc_save.datetime.min, /* Minutes. [0-59] */ 44 | .tm_hour = rtc_save.datetime.hour, /* Hours. [0-23] */ 45 | .tm_mday = rtc_save.datetime.day, /* Day. [1-31] */ 46 | .tm_mon = rtc_save.datetime.month - 1, /* Month. [0-11] */ 47 | .tm_year = rtc_save.datetime.year - 1900, /* Year - 1900. */ 48 | .tm_wday = 0, /* Day of week. [0-6] */ 49 | .tm_yday = 0, /* Days in year.[0-365] */ 50 | .tm_isdst = -1 /* DST. [-1/0/1]*/ 51 | }; 52 | rtc_save.checksum = calculate_checksum((uint32_t *)&rtc_save, 53 | offsetof(rtc_save_t, checksum)); 54 | epochtime = mktime(&timeinfo); 55 | rtc_save.datetime.dotw = timeinfo.tm_wday; 56 | // configASSERT(-1 != epochtime); 57 | } 58 | } 59 | 60 | time_t time(time_t *pxTime) { 61 | update_epochtime(); 62 | if (pxTime) { 63 | *pxTime = epochtime; 64 | } 65 | return epochtime; 66 | } 67 | 68 | void time_init() { 69 | rtc_init(); 70 | datetime_t t = {0, 0, 0, 0, 0, 0, 0}; 71 | rtc_get_datetime(&t); 72 | if (!t.year && rtc_save.datetime.year) { 73 | uint32_t xor_checksum = calculate_checksum( 74 | (uint32_t *)&rtc_save, offsetof(rtc_save_t, checksum)); 75 | if (rtc_save.signature == 0xBABEBABE && 76 | rtc_save.checksum == xor_checksum) { 77 | // Set rtc 78 | rtc_set_datetime(&rtc_save.datetime); 79 | } 80 | } 81 | } 82 | 83 | // Called by FatFs: 84 | DWORD get_fattime(void) { 85 | datetime_t t = {0, 0, 0, 0, 0, 0, 0}; 86 | bool rc = rtc_get_datetime(&t); 87 | if (!rc) return 0; 88 | 89 | DWORD fattime = 0; 90 | // bit31:25 91 | // Year origin from the 1980 (0..127, e.g. 37 for 2017) 92 | uint8_t yr = t.year - 1980; 93 | fattime |= (0b01111111 & yr) << 25; 94 | // bit24:21 95 | // Month (1..12) 96 | uint8_t mo = t.month; 97 | fattime |= (0b00001111 & mo) << 21; 98 | // bit20:16 99 | // Day of the month (1..31) 100 | uint8_t da = t.day; 101 | fattime |= (0b00011111 & da) << 16; 102 | // bit15:11 103 | // Hour (0..23) 104 | uint8_t hr = t.hour; 105 | fattime |= (0b00011111 & hr) << 11; 106 | // bit10:5 107 | // Minute (0..59) 108 | uint8_t mi = t.min; 109 | fattime |= (0b00111111 & mi) << 5; 110 | // bit4:0 111 | // Second / 2 (0..29, e.g. 25 for 50) 112 | uint8_t sd = t.sec / 2; 113 | fattime |= (0b00011111 & sd); 114 | return fattime; 115 | } 116 | -------------------------------------------------------------------------------- /pico-displayDrivs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(st7735) 2 | add_subdirectory(gfx) -------------------------------------------------------------------------------- /pico-displayDrivs/README.md: -------------------------------------------------------------------------------- 1 | # pico-displayDrivs 2 | *Display driver library for RP2040 pico-sdk* \ 3 | Example code [here](https://github.com/tvlad1234/pico-st7735Example) 4 | ## Supported display controllers: 5 | ST7735 and ST7739 in SPI mode \ 6 | ILI9341 in SPI mode 7 | 8 | ## Library usage 9 | Add the *pico-displayDrivs* subdirectory to the CMakeLists.txt of your project and include the needed libraries. 10 | 11 | ### Display driver usage: 12 | Check the readme of each driver in its corresponding folder. 13 | 14 | ### GFX Library usage: 15 | This package includes a graphics library, based on [Adafruit-GFX-Library](https://github.com/adafruit/Adafruit-GFX-Library). 16 | It supports drawing basic shapes, characters and using custom fonts. 17 | 18 | Note that the `gfx.h` header contains a convenience macro `GFX_RGB565(R, G, B)` to create a 16-bit 'rgb565' colour value from individual 8-bit components. 19 | 20 | ### GFX Framebuffer 21 | By default, the GFX library writes pixels directly to the screen. If desired, an internal framebuffer can be used (which is recomended in cases where speed is desired). The framebuffer is created using `GFX_createFramebuf()`, which automatically tells the library to write to the framebuffer. The buffer can then be pushed to the screen by calling `GFX_flush()`. If needed, the buffer can be destroyed by calling `GFX_destroyFramebuf()`. Doing so will revert to writing pixels directly to the screen. 22 | ## GFX Library Reference 23 | `GFX_drawPixel(int16_t x, int16_t y, uint16_t color);` draws a single pixel 24 | ### 25 | `GFX_drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, 26 | uint16_t bg, uint8_t size_x, uint8_t size_y);` puts a single character on screen\ 27 | `GFX_write(uint8_t c);` writes a character to the screen, handling the cursor position and text wrapping automatically\ 28 | `GFX_setCursor(int16_t x, int16_t y);` places the text cursor at the specified coordinates\ 29 | `GFX_setTextColor(uint16_t color);` sets the text color\ 30 | `GFX_setTextBack(uint16_t color);` sets the text background color\ 31 | `GFX_setFont(const GFXfont *f);` sets the used font, using the same format as [Adafruit-GFX-Library](https://github.com/adafruit/Adafruit-GFX-Library) \ 32 | `GFX_printf` prints formatted text 33 | ### 34 | `GFX_fillScreen(uint16_t color);` fills the screen with a specified color\ 35 | `GFX_setClearColor(uint16_t color);` sets the color the screen should be cleared with\ 36 | `GFX_clearScreen();` clears the screen, filling it with the color specified using the function above 37 | ### 38 | `GFX_drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color);` draws a line from (x0,y0) to (x1,y1)\ 39 | `GFX_drawFastHLine(int16_t x, int16_t y, int16_t l, uint16_t color);` draws a horizontal line\ 40 | `GFX_drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);` draws a vertical line 41 | ### 42 | `GFX_drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);` draws a rectangle\ 43 | `GFX_drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color)` draws a circle\ 44 | `GFX_fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);` draws a filled rectangle\ 45 | `GFX_fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);` draws a filled circle 46 | -------------------------------------------------------------------------------- /pico-displayDrivs/gfx/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(gfx 2 | gfx.c 3 | ) 4 | 5 | target_include_directories(gfx PUBLIC 6 | . 7 | ) 8 | 9 | target_link_libraries(gfx pico_stdlib hardware_dma) -------------------------------------------------------------------------------- /pico-displayDrivs/gfx/gfx.h: -------------------------------------------------------------------------------- 1 | #ifndef gfx_H 2 | #define gfx_H 3 | 4 | #include "pico/stdlib.h" 5 | #include "gfxfont.h" 6 | 7 | // convert 8 bit r, g, b values to 16 bit colour (rgb565 format) 8 | #define GFX_RGB565(R, G, B) ((uint16_t)(((R) & 0b11111000) << 8) | (((G) & 0b11111100) << 3) | ((B) >> 3)) 9 | 10 | void GFX_createFramebuf(); 11 | void GFX_destroyFramebuf(); 12 | 13 | void GFX_drawPixel(int16_t x, int16_t y, uint16_t color); 14 | 15 | void GFX_drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size_x, uint8_t size_y); 16 | void GFX_write(uint8_t c); 17 | void GFX_setCursor(int16_t x, int16_t y); 18 | void GFX_setTextColor(uint16_t color); 19 | void GFX_setTextBack(uint16_t color); 20 | void GFX_setFont(const GFXfont *f); 21 | 22 | void GFX_drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color); 23 | void GFX_drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); 24 | void GFX_drawFastHLine(int16_t x, int16_t y, int16_t l, uint16_t color); 25 | 26 | void GFX_drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); 27 | void GFX_fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); 28 | 29 | void GFX_fillScreen(uint16_t color); 30 | void GFX_setClearColor(uint16_t color); 31 | void GFX_clearScreen(); 32 | 33 | void GFX_drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color); 34 | void GFX_fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color); 35 | 36 | void GFX_printf(const char *format, ...); 37 | void GFX_flush(); 38 | void GFX_Update(); 39 | void GFX_scrollUp(int n); 40 | 41 | uint GFX_getWidth(); 42 | uint GFX_getHeight(); 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /pico-displayDrivs/gfx/gfxfont.h: -------------------------------------------------------------------------------- 1 | #ifndef _GFXFONT_H_ 2 | #define _GFXFONT_H_ 3 | 4 | /// Font data stored PER GLYPH 5 | typedef struct { 6 | uint16_t bitmapOffset; ///< Pointer into GFXfont->bitmap 7 | uint8_t width; ///< Bitmap dimensions in pixels 8 | uint8_t height; ///< Bitmap dimensions in pixels 9 | uint8_t xAdvance; ///< Distance to advance cursor (x axis) 10 | int8_t xOffset; ///< X dist from cursor pos to UL corner 11 | int8_t yOffset; ///< Y dist from cursor pos to UL corner 12 | } GFXglyph; 13 | 14 | /// Data stored for FONT AS A WHOLE 15 | typedef struct { 16 | uint8_t *bitmap; ///< Glyph bitmaps, concatenated 17 | GFXglyph *glyph; ///< Glyph array 18 | uint16_t first; ///< ASCII extents (first char) 19 | uint16_t last; ///< ASCII extents (last char) 20 | uint8_t yAdvance; ///< Newline distance (y axis) 21 | } GFXfont; 22 | 23 | #endif // _GFXFONT_H_ 24 | -------------------------------------------------------------------------------- /pico-displayDrivs/st7735/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(st7735 2 | st7735.c 3 | ) 4 | 5 | target_include_directories(st7735 PUBLIC 6 | . 7 | ) 8 | 9 | target_link_libraries(st7735 pico_stdlib hardware_spi hardware_dma) -------------------------------------------------------------------------------- /pico-displayDrivs/st7735/README.md: -------------------------------------------------------------------------------- 1 | ST7735 driver, based on [Adafruit-ST7735-Library](https://github.com/adafruit/Adafruit-ST7735-Library) 2 | 3 | ## Usage 4 | Add *ST7735* into CMakeLists.txt, in `target_link_libraries` 5 | 6 | ### Pin mapping 7 | By default, RST is GPIO16, CS is GPIO17, DC is GPIO20, SCK is GPIO18, TX is GPIO19, using the default SPI peripheral.\ 8 | The pin mapping can be changed using `LCD_setPins`, before initializing the display. Make sure that the chosen SCK and TX pins are usable with the selected SPI peripheral. \ 9 | Setting the reset pin to -1 disables hardware reset. \ 10 | The SPI peripheral can be selected using `LCD_setSPIperiph` 11 | 12 | 13 | ### Functions: 14 | 15 | `LCD_setPins(uint16_t dc, uint16_t cs, int16_t rst, uint16_t sck, uint16_t tx);` selects the pins used by the display \ 16 | `LCD_setSPIperiph(spi_inst_t * s);` selects the SPI peripheral used by the display \ 17 | `LCD_initDisplay(uint8_t options);` initializes the GPIO, SPI interface and display driver. It takes the same options as initR from [Adafruit-ST7735-Library](https://github.com/adafruit/Adafruit-ST7735-Library)\ 18 | `LCD_setRotation(uint8_t m);` sets the rotation\ 19 | `LCD_WritePixel(int x, int y, uint16_t col);` writes a single pixel to the screen\ 20 | `LCD_WriteBitmap(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t *bitmap);` writes a bitmap to the screen\ 21 | 22 | ### DMA usage 23 | DMA usage is disabled by default, but can be enabled by uncommenting `#define USE_DMA 1` in *st7735.h* 24 | -------------------------------------------------------------------------------- /pico-displayDrivs/st7735/st7735.h: -------------------------------------------------------------------------------- 1 | #ifndef ST7735_H 2 | #define ST7735_H 3 | #include "pico/stdlib.h" 4 | 5 | #define ST7735_TFTWIDTH_128 128 // for 1.44 and mini 6 | #define ST7735_TFTWIDTH_80 80 // for mini 7 | #define ST7735_TFTHEIGHT_128 128 // for 1.44" display 8 | #define ST7735_TFTHEIGHT_160 160 // for 1.8" and mini display 9 | 10 | // some flags for initR() :( 11 | #define INITR_GREENTAB 0x00 12 | #define INITR_REDTAB 0x01 13 | #define INITR_BLACKTAB 0x02 14 | #define INITR_18GREENTAB INITR_GREENTAB 15 | #define INITR_18REDTAB INITR_REDTAB 16 | #define INITR_18BLACKTAB INITR_BLACKTAB 17 | #define INITR_144GREENTAB 0x01 18 | #define INITR_MINI160x80 0x04 19 | #define INITR_HALLOWING 0x05 20 | 21 | // Some register settings 22 | #define ST7735_MADCTL_BGR 0x08 23 | #define ST7735_MADCTL_MH 0x04 24 | 25 | #define ST7735_FRMCTR1 0xB1 26 | #define ST7735_FRMCTR2 0xB2 27 | #define ST7735_FRMCTR3 0xB3 28 | #define ST7735_INVCTR 0xB4 29 | #define ST7735_DISSET5 0xB6 30 | 31 | #define ST7735_PWCTR1 0xC0 32 | #define ST7735_PWCTR2 0xC1 33 | #define ST7735_PWCTR3 0xC2 34 | #define ST7735_PWCTR4 0xC3 35 | #define ST7735_PWCTR5 0xC4 36 | #define ST7735_VMCTR1 0xC5 37 | 38 | #define ST7735_PWCTR6 0xFC 39 | 40 | #define ST7735_GMCTRP1 0xE0 41 | #define ST7735_GMCTRN1 0xE1 42 | 43 | #define ST_CMD_DELAY 0x80 // special signifier for command lists 44 | 45 | #define ST77XX_NOP 0x00 46 | #define ST77XX_SWRESET 0x01 47 | #define ST77XX_RDDID 0x04 48 | #define ST77XX_RDDST 0x09 49 | 50 | #define ST77XX_SLPIN 0x10 51 | #define ST77XX_SLPOUT 0x11 52 | #define ST77XX_PTLON 0x12 53 | #define ST77XX_NORON 0x13 54 | 55 | #define ST77XX_INVOFF 0x20 56 | #define ST77XX_INVON 0x21 57 | #define ST77XX_DISPOFF 0x28 58 | #define ST77XX_DISPON 0x29 59 | #define ST77XX_CASET 0x2A 60 | #define ST77XX_RASET 0x2B 61 | #define ST77XX_RAMWR 0x2C 62 | #define ST77XX_RAMRD 0x2E 63 | 64 | #define ST77XX_PTLAR 0x30 65 | #define ST77XX_TEOFF 0x34 66 | #define ST77XX_TEON 0x35 67 | #define ST77XX_MADCTL 0x36 68 | #define ST77XX_COLMOD 0x3A 69 | 70 | #define ST77XX_MADCTL_MY 0x80 71 | #define ST77XX_MADCTL_MX 0x40 72 | #define ST77XX_MADCTL_MV 0x20 73 | #define ST77XX_MADCTL_ML 0x10 74 | #define ST77XX_MADCTL_RGB 0x00 75 | 76 | #define ST77XX_RDID1 0xDA 77 | #define ST77XX_RDID2 0xDB 78 | #define ST77XX_RDID3 0xDC 79 | #define ST77XX_RDID4 0xDD 80 | 81 | // Some ready-made 16-bit ('565') color settings: 82 | #define ST77XX_BLACK 0x0000 83 | #define ST77XX_WHITE 0xFFFF 84 | #define ST77XX_RED 0xF800 85 | #define ST77XX_GREEN 0x07E0 86 | #define ST77XX_BLUE 0x001F 87 | #define ST77XX_CYAN 0x07FF 88 | #define ST77XX_MAGENTA 0xF81F 89 | #define ST77XX_YELLOW 0xFFE0 90 | #define ST77XX_ORANGE 0xFC00 91 | 92 | void LCD_setPins(uint16_t dc, uint16_t cs, int16_t rst, uint16_t sck, uint16_t tx); 93 | void LCD_initDisplay(uint8_t options); 94 | 95 | void LCD_setRotation(uint8_t m); 96 | 97 | void LCD_WriteBitmap(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t *bitmap); 98 | void LCD_WritePixel(int x, int y, uint16_t col); 99 | #endif 100 | -------------------------------------------------------------------------------- /pico-ps2Driv/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(ps2 2 | ps2.c 3 | ) 4 | 5 | target_include_directories(ps2 PUBLIC 6 | . 7 | ) 8 | 9 | target_link_libraries(ps2 pico_stdlib) -------------------------------------------------------------------------------- /pico-ps2Driv/README.md: -------------------------------------------------------------------------------- 1 | # pico-ps2Driv 2 | PS2 keyboard library for pico-sdk \ 3 | Based on [PS2Keyboard](https://github.com/PaulStoffregen/PS2Keyboard) 4 | ## Usage 5 | Add the _pico-ps2Driv_ subdirectory to the CMakeLists.txt of your project and include the library in _target_link_libraries_. 6 | ### Initializing the keyboard 7 | Before reading the keyboard, it must be initialized with _PS2_init_.\ 8 | _PS2_init_ takes the data and clock pins as a parameters.\ 9 | _Example:_ `PS2_init(3, 2);` initializes the keyboard, using GPIO3 as data and GPIO2 as clock. 10 | ### Reading the keybaord 11 | `PS2_keyAvailable()` returns 1 if there are keys to be read, 0 otherwise.\ 12 | `PS2_readKey()` returns the character associated to the next keystroke in the buffer. 13 | 14 | -------------------------------------------------------------------------------- /pico-rv32ima/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(pico-rv32ima 2 | main.c 3 | 4 | psram/psram.c 5 | cache/cache.c 6 | 7 | emulator/emulator.c 8 | 9 | console/usb_descriptors.c 10 | console/console.c 11 | console/terminal.c 12 | 13 | config/sd_hw_config.c 14 | ) 15 | 16 | # Add the standard library and FatFS/SPI to the build 17 | target_link_libraries(pico-rv32ima 18 | pico_stdlib 19 | FatFs_SPI 20 | pico_time 21 | pico_multicore 22 | hardware_vreg 23 | hardware_spi 24 | hardware_i2c 25 | hardware_clocks 26 | tinyusb_device 27 | tinyusb_board 28 | st7735 29 | gfx 30 | ps2 31 | ) 32 | 33 | target_include_directories(pico-rv32ima PUBLIC ${CMAKE_CURRENT_LIST_DIR}/console/tusb_inc ) 34 | 35 | # pico_define_boot_stage2(slower_boot2 ${PICO_DEFAULT_BOOT_STAGE2_FILE}) 36 | # target_compile_definitions(slower_boot2 PRIVATE PICO_FLASH_SPI_CLKDIV=4) 37 | 38 | # pico_set_boot_stage2(pico-rv32ima slower_boot2) 39 | 40 | pico_set_binary_type(pico-rv32ima copy_to_ram) 41 | pico_add_extra_outputs(pico-rv32ima) 42 | 43 | -------------------------------------------------------------------------------- /pico-rv32ima/cache/cache.h: -------------------------------------------------------------------------------- 1 | #ifndef CACHE_H 2 | #define CACHE_H 3 | 4 | #include 5 | 6 | void cache_write(uint32_t ofs, void *buf, uint8_t size); 7 | void cache_read(uint32_t ofs, void *buf, uint8_t size); 8 | 9 | #endif -------------------------------------------------------------------------------- /pico-rv32ima/config/rv32_config.h: -------------------------------------------------------------------------------- 1 | #ifndef _RV32_CONFIG_H 2 | #define _RV32_CONFIG_H 3 | 4 | /******************/ 5 | /* Emulator config 6 | /******************/ 7 | 8 | // RAM size in megabytes 9 | #define EMULATOR_RAM_MB 16 10 | 11 | // Image filename 12 | #define IMAGE_FILENAME "0:Image" 13 | 14 | // Time divisor 15 | #define EMULATOR_TIME_DIV 1 16 | 17 | // Tie microsecond clock to instruction count 18 | #define EMULATOR_FIXED_UPDATE false 19 | 20 | // Sleep while WFI 21 | #define EMULATOR_WFI_SLEEP false 22 | 23 | // Number of instructions per flip 24 | #define EMUALTOR_INSTR_FLIP 1024 25 | 26 | // Should Emulator fail on all faults? 27 | #define EMULAOTR_FAF false 28 | 29 | // Enable UART console 30 | #define CONSOLE_UART 1 31 | 32 | // Enable USB CDC console 33 | #define CONSOLE_CDC 0 34 | 35 | // Enable ST7735 LCD and PS/2 keyboard terminal 36 | #define CONSOLE_LCD 0 37 | 38 | #if CONSOLE_UART 39 | 40 | /******************/ 41 | /* UART config 42 | /******************/ 43 | 44 | // UART instance 45 | #define UART_INSTANCE uart0 46 | 47 | // UART Baudrate (if enabled) 48 | #define UART_BAUD_RATE 115200 49 | 50 | // Pins for the UART (if enabled) 51 | #define UART_TX_PIN 0 52 | #define UART_RX_PIN 1 53 | 54 | #endif 55 | 56 | /******************/ 57 | /* PSRAM config 58 | /******************/ 59 | 60 | // Use hardware SPI for PSRSAM (bitbang otherwise) 61 | #define PSRAM_HARDWARE_SPI 1 62 | 63 | #if PSRAM_HARDWARE_SPI 64 | 65 | // Hardware SPI instance to use for PSRAM 66 | #define PSRAM_SPI_INST spi1 67 | // PSRAM SPI speed (in MHz) 68 | #define PSRAM_SPI_SPEED 52 69 | 70 | #endif 71 | // Pins for the PSRAM SPI interface 72 | #define PSRAM_SPI_PIN_CK 10 73 | #define PSRAM_SPI_PIN_TX 11 74 | #define PSRAM_SPI_PIN_RX 12 75 | 76 | // Select lines for the two PSRAM chips 77 | #define PSRAM_SPI_PIN_S1 21 78 | #define PSRAM_SPI_PIN_S2 22 79 | #define PSRAM_SPI_PIN_S3 14 80 | #define PSRAM_SPI_PIN_S4 15 81 | 82 | // PSRAM chip size (in kilobytes) 83 | #define PSRAM_CHIP_SIZE (8192 * 1024) 84 | 85 | // Use two PSRAM chips? 86 | #define PSRAM_TWO_CHIPS 1 87 | // Use three PSRAM chips? 88 | #define PSRAM_THREE_CHIPS 0 89 | // Use four PSRAM chips? 90 | #define PSRAM_FOUR_CHIPS 0 91 | 92 | /****************/ 93 | /* SD card config 94 | /***************/ 95 | 96 | // Set to 1 to use SDIO interface for the SD. Set to 0 to use SPI. 97 | #define SD_USE_SDIO 0 98 | 99 | #if SD_USE_SDIO 100 | 101 | /****************/ 102 | /* SDIO interface 103 | /****************/ 104 | 105 | // Pins for the SDIO interface (if used) 106 | // CLK will be D0 - 2, D1 = D0 + 1, D2 = D0 + 2, D3 = D0 + 3 107 | #define SDIO_PIN_CMD 18 108 | #define SDIO_PIN_D0 19 109 | 110 | #else 111 | 112 | /*******************/ 113 | /* SD SPI interface 114 | /******************/ 115 | 116 | // SPI instance used for SD (if used) 117 | #define SD_SPI_INSTANCE spi0 118 | 119 | // Pins for the SD SPI interface (if used) 120 | #define SD_SPI_PIN_MISO 16 121 | #define SD_SPI_PIN_MOSI 19 122 | #define SD_SPI_PIN_CLK 18 123 | #define SD_SPI_PIN_CS 20 124 | #endif 125 | 126 | // #if PSRAM_HARDWARE_SPI 127 | // #undef CONSOLE_LCD 128 | // #define CONSOLE_LCD 0 129 | // #endif 130 | 131 | #if CONSOLE_LCD 132 | 133 | /*******************/ 134 | /* LCD SPI interface 135 | /******************/ 136 | 137 | // LCD INITR code 138 | #define LCD_INITR INITR_GREENTAB 139 | // Pins for the LCD SPI interface (if used) 140 | #define LCD_PIN_DC 4 141 | #define LCD_PIN_CS 6 142 | #define LCD_PIN_RST 5 143 | #define LCD_PIN_SCK 14 144 | #define LCD_PIN_TX 15 145 | 146 | /*******************/ 147 | /* PS/2 keyboard interface 148 | /******************/ 149 | 150 | #define PS2_PIN_DATA 7 151 | #define PS2_PIN_CK 8 152 | 153 | #endif 154 | 155 | /*******************/ 156 | /* Config Checks 157 | /* DO NOT MODIFY! 158 | /******************/ 159 | #if PSRAM_FOUR_CHIPS 160 | #undef PSRAM_THREE_CHIPS 161 | #undef PSRAM_TWO_CHIPS 162 | #undef CONSOLE_LCD 163 | 164 | #define PSRAM_THREE_CHIPS 0 165 | #define PSRAM_TWO_CHIPS 0 166 | #define CONSOLE_LCD 0 167 | #else 168 | #if PSRAM_THREE_CHIPS 169 | #undef PSRAM_FOUR_CHIPS 170 | #undef PSRAM_TWO_CHIPS 171 | #undef CONSOLE_LCD 172 | 173 | #define PSRAM_FOUR_CHIPS 0 174 | #define PSRAM_TWO_CHIPS 0 175 | #define CONSOLE_LCD 0 176 | #endif 177 | #endif 178 | 179 | #if !PSRAM_TWO_CHIPS && !PSRAM_THREE_CHIPS && !PSRAM_FOUR_CHIPS && PSRAM_CHIP_SIZE < (EMULATOR_RAM_MB * 1024 * 1024) 180 | #error "RAM Size too Big! 8MB < RAM" 181 | #endif 182 | #if PSRAM_TWO_CHIPS && PSRAM_CHIP_SIZE * 2 < (EMULATOR_RAM_MB * 1024 * 1024) 183 | #error "RAM Size too Big! 16MB < RAM" 184 | #endif 185 | #if PSRAM_THREE_CHIPS && PSRAM_CHIP_SIZE * 3 < (EMULATOR_RAM_MB * 1024 * 1024) 186 | #error "RAM Size too Big! 24MB < RAM" 187 | #endif 188 | #if PSRAM_FOUR_CHIPS && PSRAM_CHIP_SIZE * 4 < (EMULATOR_RAM_MB * 1024 * 1024) 189 | #error "RAM Size too Big! 32MB < RAM" 190 | #endif 191 | 192 | #endif 193 | -------------------------------------------------------------------------------- /pico-rv32ima/config/sd_hw_config.c: -------------------------------------------------------------------------------- 1 | #include "hw_config.h" 2 | #include "ff.h" /* Obtains integer types */ 3 | 4 | #include "rv32_config.h" 5 | 6 | // Hardware Configuration of SPI "objects" (if SPI is being used) 7 | #if SD_USE_SDIO == 0 8 | static spi_t spis[] = { 9 | {.hw_inst = SD_SPI_INSTANCE, // SPI component 10 | .miso_gpio = SD_SPI_PIN_MISO, // GPIO number (not Pico pin number) 11 | .mosi_gpio = SD_SPI_PIN_MOSI, 12 | .sck_gpio = SD_SPI_PIN_CLK, 13 | .set_drive_strength = true, 14 | .mosi_gpio_drive_strength = GPIO_DRIVE_STRENGTH_2MA, 15 | .sck_gpio_drive_strength = GPIO_DRIVE_STRENGTH_2MA, 16 | .baud_rate = 20 * 1000 * 1000, // Actual frequency: 20833333. 17 | .DMA_IRQ_num = DMA_IRQ_1}}; 18 | #endif 19 | 20 | // Hardware Configuration of the SD Card "objects" 21 | static sd_card_t sd_cards[] = { 22 | { 23 | .pcName = "0:", // Name used to mount device 24 | 25 | #if SD_USE_SDIO 26 | .type = SD_IF_SDIO, 27 | 28 | .sdio_if = { 29 | .CMD_gpio = SDIO_PIN_CMD, 30 | .D0_gpio = SDIO_PIN_D0, 31 | .SDIO_PIO = pio1, 32 | .DMA_IRQ_num = DMA_IRQ_0}, 33 | 34 | #else 35 | .type = SD_IF_SPI, 36 | .spi_if.spi = &spis[0], // Pointer to the SPI driving this card 37 | .spi_if.ss_gpio = SD_SPI_PIN_CS, // The SPI slave select GPIO for this SD card 38 | 39 | #endif 40 | .use_card_detect = false, 41 | .card_detect_gpio = 0, // Card detect 42 | .card_detected_true = -1 // What the GPIO read returns when a card is 43 | // present. 44 | }}; 45 | 46 | /* ********************************************************************** */ 47 | size_t sd_get_num() { return count_of(sd_cards); } 48 | sd_card_t *sd_get_by_num(size_t num) 49 | { 50 | if (num <= sd_get_num()) 51 | { 52 | return &sd_cards[num]; 53 | } 54 | else 55 | { 56 | return NULL; 57 | } 58 | } 59 | 60 | size_t spi_get_num() 61 | { 62 | #if SD_USE_SDIO 63 | return 0; 64 | #else 65 | return count_of(spis); 66 | #endif 67 | } 68 | 69 | spi_t *spi_get_by_num(size_t num) 70 | { 71 | #if SD_USE_SDIO 72 | return NULL; 73 | #else 74 | if (num <= spi_get_num()) 75 | return &spis[num]; 76 | else 77 | return NULL; 78 | #endif 79 | } 80 | 81 | /* [] END OF FILE */ 82 | -------------------------------------------------------------------------------- /pico-rv32ima/console/console.c: -------------------------------------------------------------------------------- 1 | #include "pico/stdlib.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "console.h" 8 | #include "terminal.h" 9 | 10 | #include "../config/rv32_config.h" 11 | 12 | #if CONSOLE_CDC 13 | #include "tusb.h" 14 | #endif 15 | 16 | queue_t ser_screen_queue, kb_queue; 17 | 18 | #if CONSOLE_CDC 19 | uint8_t cdc_buf[IO_QUEUE_LEN]; 20 | #endif 21 | 22 | void console_init(void) 23 | { 24 | #if CONSOLE_CDC 25 | tusb_init(); 26 | #endif 27 | 28 | #if CONSOLE_UART 29 | uart_init(UART_INSTANCE, UART_BAUD_RATE); 30 | gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART); 31 | gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART); 32 | #endif 33 | 34 | #if CONSOLE_LCD 35 | initLCDTerm(); 36 | #endif 37 | 38 | #if CONSOLE_CDC || CONSOLE_UART 39 | queue_init(&ser_screen_queue, sizeof(char), IO_QUEUE_LEN); 40 | #endif 41 | queue_init(&kb_queue, sizeof(char), IO_QUEUE_LEN); 42 | } 43 | 44 | #if CONSOLE_CDC || CONSOLE_UART 45 | void ser_console_task(void) 46 | { 47 | while (!queue_is_empty(&ser_screen_queue)) 48 | { 49 | uint8_t c; 50 | queue_remove_blocking(&ser_screen_queue, &c); 51 | 52 | #if CONSOLE_CDC 53 | if (tud_cdc_connected()) 54 | tud_cdc_write_char(c); 55 | #endif 56 | 57 | #if CONSOLE_UART 58 | uart_putc_raw(UART_INSTANCE, c); 59 | #endif 60 | } 61 | 62 | #if CONSOLE_CDC 63 | if (tud_cdc_connected() && tud_cdc_available()) 64 | { 65 | uint32_t count = tud_cdc_read(cdc_buf, sizeof(cdc_buf)); 66 | for (int i = 0; i < count; i++) 67 | queue_try_add(&kb_queue, &cdc_buf[i]); 68 | } 69 | 70 | if (tud_cdc_connected()) 71 | tud_cdc_write_flush(); 72 | #endif 73 | 74 | #if CONSOLE_UART 75 | uint8_t uart_in_ch; 76 | while (uart_is_readable(UART_INSTANCE)) 77 | { 78 | uart_read_blocking(UART_INSTANCE, &uart_in_ch, 1); 79 | queue_try_add(&kb_queue, &uart_in_ch); 80 | } 81 | #endif 82 | } 83 | #endif 84 | 85 | void console_task(void) 86 | { 87 | #if CONSOLE_CDC 88 | tud_task(); 89 | #endif 90 | 91 | #if CONSOLE_CDC || CONSOLE_UART 92 | ser_console_task(); 93 | #endif 94 | 95 | #if CONSOLE_LCD 96 | terminal_task(); 97 | #endif 98 | } 99 | 100 | void console_putc(char c) 101 | { 102 | #if CONSOLE_CDC || CONSOLE_UART 103 | queue_add_blocking(&ser_screen_queue, &c); 104 | #endif 105 | 106 | #if CONSOLE_LCD 107 | queue_add_blocking(&term_screen_queue, &c); 108 | #endif 109 | } 110 | 111 | void console_puts(char s[]) 112 | { 113 | uint8_t n = strlen(s); 114 | for (int i = 0; i < n; i++) 115 | console_putc(s[i]); 116 | } 117 | 118 | char termPrintBuf[100]; 119 | 120 | void console_printf(const char *format, ...) 121 | { 122 | va_list args; 123 | va_start(args, format); 124 | vsprintf(termPrintBuf, format, args); 125 | console_puts(termPrintBuf); 126 | va_end(args); 127 | } 128 | 129 | void console_panic(const char *format, ...) 130 | { 131 | va_list args; 132 | va_start(args, format); 133 | vsprintf(termPrintBuf, format, args); 134 | console_puts("\x1b[31mPANIC: "); 135 | console_puts(termPrintBuf); 136 | va_end(args); 137 | 138 | while (true) 139 | tight_loop_contents(); 140 | } 141 | -------------------------------------------------------------------------------- /pico-rv32ima/console/console.h: -------------------------------------------------------------------------------- 1 | #ifndef _CONSOLE_H 2 | #define _CONSOLE_H 3 | 4 | #include "pico/util/queue.h" 5 | 6 | #define IO_QUEUE_LEN 15 7 | 8 | extern queue_t ser_screen_queue, kb_queue; 9 | 10 | void console_init(void); 11 | void console_task(void); 12 | 13 | void console_putc(char c); 14 | void console_puts(char s[]); 15 | void console_printf(const char *format, ...); 16 | void console_panic(const char *format, ...); 17 | 18 | #endif -------------------------------------------------------------------------------- /pico-rv32ima/console/terminal.h: -------------------------------------------------------------------------------- 1 | #ifndef _TERMINAL_H 2 | #define _TERMINAL_H 3 | 4 | #include "pico/util/queue.h" 5 | 6 | extern queue_t term_screen_queue; 7 | 8 | void terminal_task(void); 9 | void initLCDTerm(void); 10 | 11 | #endif -------------------------------------------------------------------------------- /pico-rv32ima/console/tusb_inc/tusb_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2022 Vlad Tomoiaga (tvlad1234) 5 | * Copyright (c) 2019 Ha Thach (tinyusb.org) 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | * 25 | */ 26 | 27 | #ifndef _TUSB_CONFIG_H_ 28 | #define _TUSB_CONFIG_H_ 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | //-------------------------------------------------------------------- 35 | // COMMON CONFIGURATION 36 | //-------------------------------------------------------------------- 37 | 38 | // defined by board.mk 39 | #ifndef CFG_TUSB_MCU 40 | #error CFG_TUSB_MCU must be defined 41 | #endif 42 | 43 | // RHPort number used for device can be defined by board.mk, default to port 0 44 | #ifndef BOARD_DEVICE_RHPORT_NUM 45 | #define BOARD_DEVICE_RHPORT_NUM 0 46 | #endif 47 | 48 | // RHPort max operational speed can defined by board.mk 49 | // Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed 50 | #ifndef BOARD_DEVICE_RHPORT_SPEED 51 | #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ 52 | CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56) 53 | #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED 54 | #else 55 | #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED 56 | #endif 57 | #endif 58 | 59 | // Device mode with rhport and speed defined by board.mk 60 | #if BOARD_DEVICE_RHPORT_NUM == 0 61 | #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) 62 | #elif BOARD_DEVICE_RHPORT_NUM == 1 63 | #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) 64 | #else 65 | #error "Incorrect RHPort configuration" 66 | #endif 67 | 68 | #ifndef CFG_TUSB_OS 69 | #define CFG_TUSB_OS OPT_OS_NONE 70 | #endif 71 | 72 | // CFG_TUSB_DEBUG is defined by compiler in DEBUG build 73 | // #define CFG_TUSB_DEBUG 0 74 | 75 | /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. 76 | * Tinyusb use follows macros to declare transferring memory so that they can be put 77 | * into those specific section. 78 | * e.g 79 | * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) 80 | * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) 81 | */ 82 | #ifndef CFG_TUSB_MEM_SECTION 83 | #define CFG_TUSB_MEM_SECTION 84 | #endif 85 | 86 | #ifndef CFG_TUSB_MEM_ALIGN 87 | #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) 88 | #endif 89 | 90 | //-------------------------------------------------------------------- 91 | // DEVICE CONFIGURATION 92 | //-------------------------------------------------------------------- 93 | 94 | #ifndef CFG_TUD_ENDPOINT0_SIZE 95 | #define CFG_TUD_ENDPOINT0_SIZE 64 96 | #endif 97 | 98 | //------------- CLASS -------------// 99 | #define CFG_TUD_CDC 1 100 | #define CFG_TUD_MSC 0 101 | #define CFG_TUD_HID 0 102 | #define CFG_TUD_MIDI 0 103 | #define CFG_TUD_VENDOR 0 104 | 105 | 106 | 107 | // CDC FIFO size of TX and RX 108 | #define CFG_TUD_CDC_RX_BUFSIZE 512 109 | #define CFG_TUD_CDC_TX_BUFSIZE 512 110 | 111 | #define CFG_TUD_CDC_EP_BUFSIZE 512 112 | 113 | // MSC Buffer size of Device Mass storage 114 | #define CFG_TUD_MSC_EP_BUFSIZE 512 115 | 116 | #ifdef __cplusplus 117 | } 118 | #endif 119 | 120 | #endif /* _TUSB_CONFIG_H_ */ 121 | -------------------------------------------------------------------------------- /pico-rv32ima/emulator/emulator.h: -------------------------------------------------------------------------------- 1 | #ifndef _EMULATOR_H 2 | #define _EMULATOR_H 3 | 4 | #include 5 | 6 | enum emulatorCode{ 7 | EMU_POWEROFF, 8 | EMU_REBOOT, 9 | EMU_UNKNOWN 10 | }; 11 | 12 | int rvEmulator(); 13 | 14 | #endif -------------------------------------------------------------------------------- /pico-rv32ima/main.c: -------------------------------------------------------------------------------- 1 | #include "pico/stdlib.h" 2 | #include "pico/multicore.h" 3 | #include "pico/util/queue.h" 4 | 5 | #include "hardware/pll.h" 6 | #include "hardware/vreg.h" 7 | #include "hardware/clocks.h" 8 | 9 | #include "ff.h" 10 | #include "hw_config.h" 11 | 12 | #include "psram/psram.h" 13 | #include "emulator/emulator.h" 14 | #include "console/console.h" 15 | #include "console/terminal.h" 16 | 17 | void core1_entry(); 18 | 19 | void gset_sys_clock_pll(uint32_t vco_freq, uint post_div1, uint post_div2) 20 | { 21 | if (!running_on_fpga()) 22 | { 23 | clock_configure(clk_sys, 24 | CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX, 25 | CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB, 26 | 48 * MHZ, 27 | 48 * MHZ); 28 | 29 | pll_init(pll_sys, 1, vco_freq, post_div1, post_div2); 30 | uint32_t freq = vco_freq / (post_div1 * post_div2); 31 | 32 | // Configure clocks 33 | // CLK_REF = XOSC (12MHz) / 1 = 12MHz 34 | clock_configure(clk_ref, 35 | CLOCKS_CLK_REF_CTRL_SRC_VALUE_XOSC_CLKSRC, 36 | 0, // No aux mux 37 | 12 * MHZ, 38 | 12 * MHZ); 39 | 40 | // CLK SYS = PLL SYS (125MHz) / 1 = 125MHz 41 | clock_configure(clk_sys, 42 | CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX, 43 | CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS, 44 | freq, freq); 45 | 46 | clock_configure(clk_peri, 47 | 0, 48 | CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS, 49 | freq, 50 | freq); 51 | } 52 | } 53 | 54 | static inline bool gset_sys_clock_khz(uint32_t freq_khz, bool required) 55 | { 56 | uint vco, postdiv1, postdiv2; 57 | if (check_sys_clock_khz(freq_khz, &vco, &postdiv1, &postdiv2)) 58 | { 59 | gset_sys_clock_pll(vco, postdiv1, postdiv2); 60 | return true; 61 | } 62 | else if (required) 63 | { 64 | panic("System clock of %u kHz cannot be exactly achieved", freq_khz); 65 | } 66 | return false; 67 | } 68 | 69 | int main() 70 | { 71 | 72 | sleep_ms(50); 73 | vreg_set_voltage(VREG_VOLTAGE_MAX); // overvolt the core just a bit 74 | sleep_ms(50); 75 | gset_sys_clock_khz(438000, true); // overclock to 400 MHz (from 125MHz) 76 | sleep_ms(50); 77 | console_init(); 78 | 79 | multicore_reset_core1(); 80 | multicore_fifo_drain(); 81 | multicore_launch_core1(core1_entry); 82 | 83 | while (true) 84 | { 85 | console_task(); 86 | } 87 | } 88 | 89 | void core1_entry() 90 | { 91 | int r = initPSRAM(); 92 | if (r < 1) 93 | console_panic("Error initalizing PSRAM (%d)!\n\r", r); 94 | 95 | console_printf("\x1b[32mPSRAM init OK!\n\r"); 96 | console_printf("\x1b[32mPSRAM Baud: %d\n\r", r); 97 | 98 | sd_card_t *pSD0 = sd_get_by_num(0); 99 | FRESULT fr = f_mount(&pSD0->fatfs, pSD0->pcName, 1); 100 | if (FR_OK != fr) 101 | console_panic("SD mount error: %s (%d)\n\r", FRESULT_str(fr), fr); 102 | 103 | gpio_init(2); 104 | gpio_set_dir(2, GPIO_IN); 105 | gpio_pull_up(2); 106 | 107 | int c = rvEmulator(); 108 | 109 | while (c == EMU_REBOOT) 110 | c = rvEmulator(); 111 | } 112 | -------------------------------------------------------------------------------- /pico-rv32ima/psram/psram.h: -------------------------------------------------------------------------------- 1 | #ifndef __PSRAM_H 2 | #define __PSRAM_H 3 | 4 | #include "pico/stdlib.h" 5 | #include "../config/rv32_config.h" 6 | 7 | void accessPSRAM(uint32_t addr, size_t size, bool write, void *bufP); 8 | int initPSRAM(); 9 | void RAMGetStat(uint64_t* reads, uint64_t* writes); 10 | 11 | // PSRAM bypass 12 | // #define cache_write(ofs, buf, size) accessPSRAM(ofs, size, true, buf) 13 | // #define cache_read(ofs, buf, size) accessPSRAM(ofs, size, false, buf) 14 | 15 | #endif -------------------------------------------------------------------------------- /pico_sdk_import.cmake: -------------------------------------------------------------------------------- 1 | # This is a copy of /external/pico_sdk_import.cmake 2 | 3 | # This can be dropped into an external project to help locate this SDK 4 | # It should be include()ed prior to project() 5 | 6 | if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) 7 | set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) 8 | message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") 9 | endif () 10 | 11 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) 12 | set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) 13 | message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") 14 | endif () 15 | 16 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) 17 | set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) 18 | message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") 19 | endif () 20 | 21 | set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") 22 | set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") 23 | set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") 24 | 25 | if (NOT PICO_SDK_PATH) 26 | if (PICO_SDK_FETCH_FROM_GIT) 27 | include(FetchContent) 28 | set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) 29 | if (PICO_SDK_FETCH_FROM_GIT_PATH) 30 | get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") 31 | endif () 32 | FetchContent_Declare( 33 | pico_sdk 34 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 35 | GIT_TAG master 36 | ) 37 | if (NOT pico_sdk) 38 | message("Downloading Raspberry Pi Pico SDK") 39 | FetchContent_Populate(pico_sdk) 40 | set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) 41 | endif () 42 | set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) 43 | else () 44 | message(FATAL_ERROR 45 | "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." 46 | ) 47 | endif () 48 | endif () 49 | 50 | get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") 51 | if (NOT EXISTS ${PICO_SDK_PATH}) 52 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") 53 | endif () 54 | 55 | set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) 56 | if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) 57 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") 58 | endif () 59 | 60 | set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) 61 | 62 | include(${PICO_SDK_INIT_CMAKE_FILE}) 63 | -------------------------------------------------------------------------------- /pictures/lcd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElectroBoy404NotFound/pico-linux/5d4eda10c2a3d2b18f0711ebbd690f17bba46fb8/pictures/lcd.jpg -------------------------------------------------------------------------------- /pictures/screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElectroBoy404NotFound/pico-linux/5d4eda10c2a3d2b18f0711ebbd690f17bba46fb8/pictures/screenshot.jpg --------------------------------------------------------------------------------