From 9d031dcf629845decf916e5b1579fda052ac8ac9 Mon Sep 17 00:00:00 2001 From: Charlie Birks Date: Mon, 4 Oct 2021 13:54:40 +0100 Subject: [PATCH 1/6] pico: Add a storage_init function --- 32blit-pico/file.cpp | 6 ++++-- 32blit-pico/storage.cpp | 4 ++++ 32blit-pico/storage.hpp | 2 ++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/32blit-pico/file.cpp b/32blit-pico/file.cpp index 422cf3697..aa9f42f80 100644 --- a/32blit-pico/file.cpp +++ b/32blit-pico/file.cpp @@ -12,16 +12,18 @@ #include "storage.hpp" static FATFS fs; +static bool initialised = false; std::vector open_files; // fatfs io funcs DSTATUS disk_initialize(BYTE pdrv) { - return RES_OK; + initialised = storage_init(); + return initialised ? RES_OK : STA_NOINIT; } DSTATUS disk_status(BYTE pdrv) { - return RES_OK; // FIXME: NOINIT? + return initialised ? RES_OK : STA_NOINIT; } DRESULT disk_read(BYTE pdrv, BYTE *buff, LBA_t sector, UINT count) { diff --git a/32blit-pico/storage.cpp b/32blit-pico/storage.cpp index 265efdc02..a7bee1ce1 100644 --- a/32blit-pico/storage.cpp +++ b/32blit-pico/storage.cpp @@ -15,6 +15,10 @@ static const uint32_t storage_offset = PICO_FLASH_SIZE_BYTES - storage_size; extern bool core1_started; +bool storage_init() { + return true; +} + void get_storage_size(uint16_t &block_size, uint32_t &num_blocks) { block_size = FLASH_SECTOR_SIZE; num_blocks = storage_size / FLASH_SECTOR_SIZE; diff --git a/32blit-pico/storage.hpp b/32blit-pico/storage.hpp index e1b7ac4dd..a6789c875 100644 --- a/32blit-pico/storage.hpp +++ b/32blit-pico/storage.hpp @@ -1,6 +1,8 @@ #pragma once #include +bool storage_init(); + void get_storage_size(uint16_t &block_size, uint32_t &num_blocks); int32_t storage_read(uint32_t sector, uint32_t offset, void *buffer, uint32_t size_bytes); From 291b190c834f05b787853ebf02ffa5caac5b8c08 Mon Sep 17 00:00:00 2001 From: Charlie Birks Date: Mon, 30 Jan 2023 16:42:43 +0000 Subject: [PATCH 2/6] pico: driver-ify flash storage --- 32blit-pico/CMakeLists.txt | 5 ++++- 32blit-pico/{storage.cpp => storage_flash.cpp} | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) rename 32blit-pico/{storage.cpp => storage_flash.cpp} (97%) diff --git a/32blit-pico/CMakeLists.txt b/32blit-pico/CMakeLists.txt index b858dc608..dba6eb61f 100644 --- a/32blit-pico/CMakeLists.txt +++ b/32blit-pico/CMakeLists.txt @@ -38,7 +38,6 @@ target_sources(BlitHalPico INTERFACE ${CMAKE_CURRENT_LIST_DIR}/file.cpp ${CMAKE_CURRENT_LIST_DIR}/led.cpp ${CMAKE_CURRENT_LIST_DIR}/main.cpp - ${CMAKE_CURRENT_LIST_DIR}/storage.cpp ${CMAKE_CURRENT_LIST_DIR}/multiplayer.cpp ${CMAKE_CURRENT_LIST_DIR}/st7789.cpp ${CMAKE_CURRENT_LIST_DIR}/usb_descriptors.c @@ -99,6 +98,9 @@ endif() if(NOT BLIT_INPUT_DRIVER) set(BLIT_INPUT_DRIVER "none") endif() +if(NOT BLIT_STORAGE_DRIVER) + set(BLIT_STORAGE_DRIVER "flash") +endif() if(NOT BLIT_USB_DRIVER) set(BLIT_USB_DRIVER "device") endif() @@ -145,6 +147,7 @@ target_sources(BlitHalPico INTERFACE ${CMAKE_CURRENT_LIST_DIR}/audio_${BLIT_AUDIO_DRIVER}.cpp ${CMAKE_CURRENT_LIST_DIR}/display_${BLIT_DISPLAY_DRIVER}.cpp ${CMAKE_CURRENT_LIST_DIR}/input_${BLIT_INPUT_DRIVER}.cpp + ${CMAKE_CURRENT_LIST_DIR}/storage_${BLIT_STORAGE_DRIVER}.cpp ${CMAKE_CURRENT_LIST_DIR}/usb_${BLIT_USB_DRIVER}.cpp ) diff --git a/32blit-pico/storage.cpp b/32blit-pico/storage_flash.cpp similarity index 97% rename from 32blit-pico/storage.cpp rename to 32blit-pico/storage_flash.cpp index a7bee1ce1..c2312028c 100644 --- a/32blit-pico/storage.cpp +++ b/32blit-pico/storage_flash.cpp @@ -1,4 +1,4 @@ -// raw storage interface, currently flash +// raw flash storage interface #include "storage.hpp" #include From cbafd705da63b65dab0da8a750a58b920f18666e Mon Sep 17 00:00:00 2001 From: Charlie Birks Date: Wed, 6 Oct 2021 12:47:22 +0100 Subject: [PATCH 3/6] pico: Add SD card based storage Hmm, that's a lot of code --- 32blit-pico/CMakeLists.txt | 5 + 32blit-pico/ffconf.h | 7 +- 32blit-pico/spi.pio | 4 + 32blit-pico/storage_sd_spi.cpp | 464 +++++++++++++++++++++++++++++++++ 4 files changed, 479 insertions(+), 1 deletion(-) create mode 100644 32blit-pico/spi.pio create mode 100644 32blit-pico/storage_sd_spi.cpp diff --git a/32blit-pico/CMakeLists.txt b/32blit-pico/CMakeLists.txt index dba6eb61f..924174338 100644 --- a/32blit-pico/CMakeLists.txt +++ b/32blit-pico/CMakeLists.txt @@ -126,6 +126,10 @@ if(BLIT_INPUT_DRIVER STREQUAL "usb_hid") list(APPEND BLIT_BOARD_DEFINITIONS INPUT_USB_HID) endif() +if(BLIT_STORAGE_DRIVER STREQUAL "sd_spi") + list(APPEND BLIT_BOARD_DEFINITIONS STORAGE_SD) +endif() + if(BLIT_USB_DRIVER STREQUAL "host") list(APPEND BLIT_BOARD_DEFINITIONS USB_HOST) list(APPEND BLIT_BOARD_LIBRARIES tinyusb_host) @@ -141,6 +145,7 @@ pico_sdk_init() # generate PIO headers (has to be after SDK init) pico_generate_pio_header(BlitHalPico ${CMAKE_CURRENT_LIST_DIR}/st7789.pio) +pico_generate_pio_header(BlitHalPico ${CMAKE_CURRENT_LIST_DIR}/spi.pio) # driver sources target_sources(BlitHalPico INTERFACE diff --git a/32blit-pico/ffconf.h b/32blit-pico/ffconf.h index 2fa147243..2a0d33914 100644 --- a/32blit-pico/ffconf.h +++ b/32blit-pico/ffconf.h @@ -192,9 +192,14 @@ / arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk() / funciton will be available. */ - +#ifdef STORAGE_SD +#define FF_MIN_SS 512 +#define FF_MAX_SS 512 +#else #define FF_MIN_SS 4096 #define FF_MAX_SS 4096 +#endif + /* This set of options configures the range of sector size to be supported. (512, / 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and / harddisk, but a larger value may be required for on-board flash memory and some diff --git a/32blit-pico/spi.pio b/32blit-pico/spi.pio new file mode 100644 index 000000000..029056558 --- /dev/null +++ b/32blit-pico/spi.pio @@ -0,0 +1,4 @@ +.program spi_cpha0 +.side_set 1 + out pins, 1 side 0 + in pins, 1 side 1 diff --git a/32blit-pico/storage_sd_spi.cpp b/32blit-pico/storage_sd_spi.cpp new file mode 100644 index 000000000..2cbdc001e --- /dev/null +++ b/32blit-pico/storage_sd_spi.cpp @@ -0,0 +1,464 @@ +// SPI SD card storage interface +#include "storage.hpp" + +#include "pico/time.h" +#include "pico/binary_info.h" + +#include "engine/engine.hpp" + +#include "config.h" + +#include "spi.pio.h" + +// vga board pins +#define SD_SCK 5 +#define SD_MOSI 18 +#define SD_MISO 19 +#define SD_CS 22 + +#define SD_TIMEOUT 10 + +static PIO sd_pio = pio1; +static int sd_sm = 0; +static bool sd_io_initialised = false; + +static uint32_t card_size_blocks = 0; +static bool is_hcs = false; + +static void spi_write(const uint8_t *buf, size_t len) { + size_t tx_remain = len, rx_remain = len; + auto txfifo = (io_rw_8 *) &sd_pio->txf[sd_sm]; + auto rxfifo = (io_rw_8 *) &sd_pio->rxf[sd_sm]; + + while (tx_remain || rx_remain) { + if (tx_remain && !pio_sm_is_tx_fifo_full(sd_pio, sd_sm)) { + *txfifo = *buf++; + --tx_remain; + } + if (rx_remain && !pio_sm_is_rx_fifo_empty(sd_pio, sd_sm)) { + (void) *rxfifo; + --rx_remain; + } + } +} + +static void spi_read(uint8_t *buf, size_t len) { + size_t tx_remain = len, rx_remain = len; + auto txfifo = (io_rw_8 *) &sd_pio->txf[sd_sm]; + auto rxfifo = (io_rw_8 *) &sd_pio->rxf[sd_sm]; + + while (tx_remain || rx_remain) { + if (tx_remain && !pio_sm_is_tx_fifo_full(sd_pio, sd_sm)) { + *txfifo = 0xFF; + --tx_remain; + } + if (rx_remain && !pio_sm_is_rx_fifo_empty(sd_pio, sd_sm)) { + *buf++ = *rxfifo; + --rx_remain; + } + } +} + +static uint8_t spi_transfer_byte(uint8_t b) { + while(pio_sm_is_tx_fifo_full(sd_pio, sd_sm)); + *(io_rw_8 *)&sd_pio->txf[sd_sm] = b; + + while(pio_sm_is_rx_fifo_empty(sd_pio, sd_sm)); + return *(io_rw_8 *)&sd_pio->rxf[sd_sm]; +} + +static bool sd_wait_ready() { + absolute_time_t timeout_time = make_timeout_time_ms(SD_TIMEOUT); + + while(spi_transfer_byte(0xFF) != 0xFF) { + if(absolute_time_diff_us(get_absolute_time(), timeout_time) <= 0) + return false; + } + + return true; +} + +static bool sd_begin() { + gpio_put(SD_CS, 0); + + // wait for ready + if(!sd_wait_ready()) { + gpio_put(SD_CS, 1); + return false; + } + + return true; +} + +static void sd_end() { + gpio_put(SD_CS, 1); + spi_transfer_byte(0xFF); +} + +static void sd_write_command(uint8_t cmd, uint32_t param, uint8_t crc) { + uint8_t buf[]{ + uint8_t(0x40 | cmd), + uint8_t(param >> 24), + uint8_t(param >> 16), + uint8_t(param >> 8), + uint8_t(param), + crc + }; + + spi_write(buf, sizeof(buf)); +} + +uint8_t sd_read_response() { + uint8_t ret = 0; + int attempt = 0; + while(((ret = spi_transfer_byte(0xFF)) & 0x80) && (attempt++ < 8)); + + return ret; +} + +static uint8_t sd_command1(uint8_t cmd, uint32_t param, uint8_t crc = 1) { + if(!sd_begin()) + return 0xFF; + + sd_write_command(cmd, param, crc); + uint8_t res = sd_read_response(); + + sd_end(); + return res; +} + +static uint8_t sd_command3_7(uint8_t cmd, uint32_t param, uint32_t &res_data, uint8_t crc = 1) { + if(!sd_begin()) + return 0xFF; + + sd_write_command(cmd, param, crc); + + uint8_t res = sd_read_response(); + + // no error bits + if((res & 0xFE) == 0) { + spi_read((uint8_t *)&res_data, 4); + res_data = __builtin_bswap32(res_data); + } + + sd_end(); + return res; +} + +static bool sd_read_block(uint8_t *buffer, int len) { + // wait for start token + absolute_time_t timeout_time = make_timeout_time_ms(SD_TIMEOUT * 10); + + while(spi_transfer_byte(0xFF) != 0xFE) { + if(absolute_time_diff_us(get_absolute_time(), timeout_time) <= 0) + return false; + } + + spi_read(buffer, len); + + // crc + spi_transfer_byte(0xFF); + spi_transfer_byte(0xFF); + + return true; +} + +static uint8_t sd_command_read_block(uint8_t cmd, uint32_t addr, uint8_t *buffer) { + if(!sd_begin()) + return 0xFF; + + sd_write_command(cmd, addr, 1); + + uint8_t res = sd_read_response(); + + if(res == 0) { + int len = 512; + if(cmd == 9 || cmd == 10) // CSD/CID are 16 bytes + len = 16; + else if(cmd == 6) // SWITCH + len = 64; + + if(!sd_read_block(buffer, len)) + return 0xFF; + } + + sd_end(); + + return res; +} + +static uint8_t sd_command_read_block_multiple(uint8_t cmd, uint32_t addr, uint8_t *buffer, int count, uint32_t &read) { + if(!sd_begin()) + return 0xFF; + + sd_write_command(cmd, addr, 1); + + uint8_t res = sd_read_response(); + + if(res == 0) { + // likely only used with CMD 18 + const int len = 512; + + while(count--) { + if(!sd_read_block(buffer, len)) + return 0xFF; + + read += len; + buffer += len; + } + + // now CMD12 to end + sd_write_command(12, 0, 1); // STOP_TRANSMISSION + spi_transfer_byte(0xFF); // stuff byte + sd_read_response(); + } + + sd_end(); + + return res; +} + +static uint8_t sd_command_write_block(uint8_t cmd, uint32_t addr, const uint8_t *buffer) { + if(!sd_begin()) + return 0xFF; + + sd_write_command(cmd, addr, 1); + + uint8_t res = sd_read_response(); + + if(res == 0) { + if(!sd_wait_ready()) { + sd_end(); + return 0xFF; + } + + spi_transfer_byte(0xFE); // start token (different for CMD25) + + int len = 512; + + for(int i = 0; i < len; i++) + spi_transfer_byte(*buffer++); + + // crc + spi_transfer_byte(0xFF); + spi_transfer_byte(0xFF); + + auto dataRes = spi_transfer_byte(0xFF) & 0x1F; + + // check accepted + if(dataRes != 0x5) { + sd_end(); + return 0xFF; + } + + // wait for not busy + while(spi_transfer_byte(0xFF) == 0); + } + + sd_end(); + return res; +} + +bool storage_init() { + bi_decl_if_func_used(bi_4pins_with_names(SD_MISO, "SD RX", SD_MOSI, "SD TX", SD_SCK, "SD SCK", SD_CS, "SD CS")); + + // this will be called again it it fails + if(!sd_io_initialised) { + uint offset = pio_add_program(sd_pio, &spi_cpha0_program); + + sd_sm = pio_claim_unused_sm(sd_pio, true); + + pio_sm_config c = spi_cpha0_program_get_default_config(offset); + + sm_config_set_out_pins(&c, SD_MOSI, 1); + sm_config_set_in_pins(&c, SD_MISO); + sm_config_set_sideset_pins(&c, SD_SCK); + + sm_config_set_out_shift(&c, false, true, 8); + sm_config_set_in_shift(&c, false, true, 8); + + // MOSI, SCK output are low, MISO is input + pio_sm_set_pins_with_mask(sd_pio, sd_sm, 0, (1u << SD_SCK) | (1u << SD_MOSI)); + pio_sm_set_pindirs_with_mask(sd_pio, sd_sm, (1u << SD_SCK) | (1u << SD_MOSI), (1u << SD_SCK) | (1u << SD_MOSI) | (1u << SD_MISO)); + pio_gpio_init(sd_pio, SD_MOSI); + pio_gpio_init(sd_pio, SD_MISO); + pio_gpio_init(sd_pio, SD_SCK); + + gpio_pull_up(SD_MISO); + + // SPI is synchronous, so bypass input synchroniser to reduce input delay. + hw_set_bits(&sd_pio->input_sync_bypass, 1u << SD_MISO); + + pio_sm_init(sd_pio, sd_sm, offset, &c); + pio_sm_set_enabled(sd_pio, sd_sm, true); + + // CS + gpio_init(SD_CS); + gpio_set_dir(SD_CS, GPIO_OUT); + gpio_put(SD_CS, 1); + + sd_io_initialised = true; + } + + // go slow for init + pio_sm_set_clkdiv(sd_pio, sd_sm, 250); + + uint8_t buf[]{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + spi_write(buf, sizeof(buf)); + + // send cmd0 + uint8_t res = 0xFF; + for(int retry = 0; retry < 16 && res == 0xFF; retry++) + res = sd_command1(0, 0, 0x95); // GO_IDLE_STATE + + if(res != 0x1) { + blit::debugf("CMD0 failed (res %X)\n", res); + return false; + } + + // check voltage range / check if SDv2 + bool is_v2 = true; + + uint32_t data; + res = sd_command3_7(8, 0x1AA, data, 0x87); // SEND_IF_COND + + if(res == 5) { + // not supported, old card + is_v2 = false; + } else if(res != 1) { + blit::debugf("CMD8 failed (res %X)\n", res); + return false; + } else if(data != 0x1AA) { + blit::debugf("CMD8 returned unexpected %X!\n", data); + return false; + } + + // init + while(res != 0) { + res = sd_command1(55, 0, 0x65); // APP_CMD + + if(res == 0x1) + res = sd_command1(41, is_v2 ? 0x40000000 : 0, is_v2 ? 0x77 : 0xE5); // APP_SEND_OP_COND + else if(res != 0xFF) { + blit::debugf("CMD55 failed (res %X)\n", res); + return false; + } + + if(res > 1 && res != 0xFF) { + blit::debugf("ACMD41 failed (res %X)\n", res); + return false; + } + } + + // defaults, but make sure + sd_command1(59, 0); // CRC_ON_OFF + sd_command1(16, 512); // SET_BLOCKLEN + + // read OCR + res = sd_command3_7(58, 0, data); // READ_OCR + if(res != 0) { + blit::debugf("CMD58 failed (res %X)\n", res); + return false; + } + + is_hcs = false; + if((data & 0xC0000000) == 0xC0000000) + is_hcs = true; + + // read CSD + uint8_t csd[16]; + res = sd_command_read_block(9, 0, csd); // SEND_CSD + + if(res != 0) { + blit::debugf("CMD9 failed (res %X)\n", res); + return false; + } + + // v1 + if((csd[0] >> 6) == 0) { + int c_size = ((csd[6] & 0x3) << 10) | (csd[7] << 2) | (csd[8] >> 6); + int c_size_mult = ((csd[9] & 0x3) << 1) | (csd[10] >> 7); + int readBlLen = csd[5] & 0xF; + + uint32_t num_blocks = uint32_t(c_size + 1) * (2 << (c_size_mult + 1)); + uint32_t size_bytes = num_blocks * (2 << (readBlLen - 1)); + card_size_blocks = size_bytes / 512; + } else { // v2 + // measured in 512k blocks + card_size_blocks = (((int32_t(csd[7] & 0x3F) << 16) | (uint32_t(csd[8]) << 8) | csd[9]) + 1) * 1024; + } + + blit::debugf("Detected %s card, size %i blocks\n", is_v2 ? (is_hcs ? "SDHC" : "SDv2") : "SDv1", card_size_blocks); + + // set speed (PIO program is 2 cycles/clock) + // these are a little fast + int div = 2; // 125/(2*2) = 31.25MHz + +#if OVERCLOCK_250 + div *= 2; +#endif + + // attempt high speed + uint8_t switch_res[64]; + if(sd_command_read_block(6, 0x80FFFFF1, switch_res) == 0) { // SWITCH + if((switch_res[16] & 0xF) == 1) + div /= 2; // successful switch, double speed + } + + pio_sm_set_clkdiv(sd_pio, sd_sm, div); + pio_sm_restart(sd_pio, sd_sm); + + return true; +} + +void get_storage_size(uint16_t &block_size, uint32_t &num_blocks) { + block_size = 512; + num_blocks = card_size_blocks; +} + +int32_t storage_read(uint32_t sector, uint32_t offset, void *buffer, uint32_t size_bytes) { + // offset should be 0 (block size == msc buffer size) + + if(!is_hcs) + sector *= 512; + + auto blocks = size_bytes / 512; + + if(blocks == 1) { + if(sd_command_read_block(17, sector, (uint8_t *)buffer) != 0) // READ_SINGLE_BLOCK + return 0; + + return size_bytes; + } else { + uint32_t read = 0; + sd_command_read_block_multiple(18, sector, (uint8_t *)buffer, blocks, read); + return read; + } + + return size_bytes; +} + +int32_t storage_write(uint32_t sector, uint32_t offset, const uint8_t *buffer, uint32_t size_bytes) { + // offset should be 0 + + if(!is_hcs) + sector *= 512; + + auto blocks = size_bytes / 512; + + int32_t written = 0; + + // TODO: multi block writes + while(blocks--) { + if(sd_command_write_block(24, sector, (uint8_t *)buffer + written) != 0) // WRITE_SINGLE_BLOCK + break; + + written += 512; + if(!is_hcs) + sector += 512; + else + sector++; + } + + return written; +} From 91436bda8115fc2d7a7a9e81164bb83d277125bb Mon Sep 17 00:00:00 2001 From: Charlie Birks Date: Wed, 20 Oct 2021 14:22:26 +0100 Subject: [PATCH 4/6] pico: Don't auto-format SD cards --- 32blit-pico/file.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/32blit-pico/file.cpp b/32blit-pico/file.cpp index aa9f42f80..672e62294 100644 --- a/32blit-pico/file.cpp +++ b/32blit-pico/file.cpp @@ -59,6 +59,8 @@ DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void* buff) { void init_fs() { auto res = f_mount(&fs, "", 1); + // auto-format flash, but not SD cards +#ifndef STORAGE_SD if(res == FR_NO_FILESYSTEM) { printf("No filesystem found, formatting...\n"); @@ -73,6 +75,7 @@ void init_fs() { res = f_mount(&fs, "", 1); } +#endif if(res != FR_OK) printf("Failed to mount filesystem! (%i)\n", res); From f550668087a2ba3cc5c7257609471157310343d3 Mon Sep 17 00:00:00 2001 From: Charlie Birks Date: Mon, 30 Jan 2023 18:03:38 +0000 Subject: [PATCH 5/6] pico: enable SD card for VGA board --- 32blit-pico/board/vgaboard/config.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/32blit-pico/board/vgaboard/config.cmake b/32blit-pico/board/vgaboard/config.cmake index 7b3463b50..27fcf6ce5 100644 --- a/32blit-pico/board/vgaboard/config.cmake +++ b/32blit-pico/board/vgaboard/config.cmake @@ -9,4 +9,5 @@ set(BLIT_BOARD_DEFINITIONS blit_driver(audio i2s) blit_driver(display scanvideo) blit_driver(input usb_hid) +blit_driver(storage sd_spi) blit_driver(usb host) From 1d6c5af86ee7911988ec7065f7ae8df0fe28d8bf Mon Sep 17 00:00:00 2001 From: Charlie Birks Date: Thu, 13 Jul 2023 20:59:14 +0100 Subject: [PATCH 6/6] pico: move SPI SD pins to config.h --- 32blit-pico/board/vgaboard/config.h | 6 ++++++ 32blit-pico/storage_sd_spi.cpp | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/32blit-pico/board/vgaboard/config.h b/32blit-pico/board/vgaboard/config.h index 5beeeebff..d325fb669 100644 --- a/32blit-pico/board/vgaboard/config.h +++ b/32blit-pico/board/vgaboard/config.h @@ -3,3 +3,9 @@ #ifndef ALLOW_HIRES #define ALLOW_HIRES 0 // disable by default, mode switching isn't supported #endif + +// spi +#define SD_SCK 5 +#define SD_MOSI 18 +#define SD_MISO 19 +#define SD_CS 22 diff --git a/32blit-pico/storage_sd_spi.cpp b/32blit-pico/storage_sd_spi.cpp index 2cbdc001e..06c374ae1 100644 --- a/32blit-pico/storage_sd_spi.cpp +++ b/32blit-pico/storage_sd_spi.cpp @@ -10,12 +10,6 @@ #include "spi.pio.h" -// vga board pins -#define SD_SCK 5 -#define SD_MOSI 18 -#define SD_MISO 19 -#define SD_CS 22 - #define SD_TIMEOUT 10 static PIO sd_pio = pio1;