Skip to content

Commit

Permalink
Add SD card speed class warning
Browse files Browse the repository at this point in the history
This change warns the user if they are using an SD card below the speed
class of 10.

Based on the ZuluSCSI commit ZuluSCSI/ZuluSCSI-firmware@28f68ac
which is based off of BlueSCSI/BlueSCSI-v2#191

Co-authored-by: androda <[email protected]>
  • Loading branch information
morio and androda committed Oct 4, 2024
1 parent 2c40642 commit 7996923
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 23 deletions.
41 changes: 35 additions & 6 deletions lib/ZuluIDE_platform_RP2040/rp2040_sdio.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/**
* ZuluIDE™ - Copyright (c) 2023 Rabbit Hole Computing™
* ZuluIDE™ - Copyright (c) 2023-2024 Rabbit Hole Computing™
* Copyright (c) 2024 Tech by Androda, LLC
*
* ZuluIDE™ firmware is licensed under the GPL version 3 or any later version. 
* ZuluIDE™ firmware is licensed under the GPL version 3 or any later version.
*
* https://www.gnu.org/licenses/gpl-3.0.html
* ----
Expand Down Expand Up @@ -369,7 +370,7 @@ sdio_status_t rp2040_sdio_command_R3(uint8_t command, uint32_t arg, uint32_t *re
* Data reception from SD card
*******************************************************/

sdio_status_t rp2040_sdio_rx_start(uint8_t *buffer, uint32_t num_blocks)
sdio_status_t rp2040_sdio_rx_start(uint8_t *buffer, uint32_t num_blocks, uint32_t block_size)
{
// Buffer must be aligned
assert(((uint32_t)buffer & 3) == 0 && num_blocks <= SDIO_MAX_BLOCKS);
Expand All @@ -386,8 +387,8 @@ sdio_status_t rp2040_sdio_rx_start(uint8_t *buffer, uint32_t num_blocks)
// and then 8 bytes to g_sdio.received_checksums.
for (int i = 0; i < num_blocks; i++)
{
g_sdio.dma_blocks[i * 2].write_addr = buffer + i * SDIO_BLOCK_SIZE;
g_sdio.dma_blocks[i * 2].transfer_count = SDIO_BLOCK_SIZE / sizeof(uint32_t);
g_sdio.dma_blocks[i * 2].write_addr = buffer + i * block_size;
g_sdio.dma_blocks[i * 2].transfer_count = block_size / sizeof(uint32_t);

g_sdio.dma_blocks[i * 2 + 1].write_addr = &g_sdio.received_checksums[i];
g_sdio.dma_blocks[i * 2 + 1].transfer_count = 2;
Expand Down Expand Up @@ -419,7 +420,7 @@ sdio_status_t rp2040_sdio_rx_start(uint8_t *buffer, uint32_t num_blocks)
pio_sm_set_consecutive_pindirs(SDIO_PIO, SDIO_DATA_SM, SDIO_D0, 4, false);

// Write number of nibbles to receive to Y register
pio_sm_put(SDIO_PIO, SDIO_DATA_SM, SDIO_BLOCK_SIZE * 2 + 16 - 1);
pio_sm_put(SDIO_PIO, SDIO_DATA_SM, block_size * 2 + 16 - 1);
pio_sm_exec(SDIO_PIO, SDIO_DATA_SM, pio_encode_out(pio_y, 32));

// Enable RX FIFO join because we don't need the TX FIFO during transfer.
Expand Down Expand Up @@ -749,6 +750,34 @@ sdio_status_t rp2040_sdio_stop()
return SDIO_OK;
}

/*******************************************************
* Status Register Receiver
*******************************************************/
sdio_status_t receive_status_register(uint8_t* sds) {
rp2040_sdio_rx_start(sds, 1, 64);
// Wait for the DMA operation to complete, or fail if it took too long
waitagain:
while (dma_channel_is_busy(SDIO_DMA_CHB) || dma_channel_is_busy(SDIO_DMA_CH))
{
if ((uint32_t)(millis() - g_sdio.transfer_start_time) > 2)
{
// Reset the state machine program
dma_channel_abort(SDIO_DMA_CHB);
pio_sm_set_enabled(SDIO_PIO, SDIO_CMD_SM, false);
pio_sm_clear_fifos(SDIO_PIO, SDIO_CMD_SM);
return SDIO_ERR_RESPONSE_TIMEOUT;
}
}
// Assert that both DMA channels are complete
if(dma_channel_is_busy(SDIO_DMA_CHB) || dma_channel_is_busy(SDIO_DMA_CH)) {
// Wait failure, go back.
goto waitagain;
}
pio_sm_set_enabled(SDIO_PIO, SDIO_DATA_SM, false);
g_sdio.transfer_state = SDIO_IDLE;
return SDIO_OK;
}

void rp2040_sdio_init(int clock_divider)
{
// Mark resources as being in use, unless it has been done already.
Expand Down
5 changes: 4 additions & 1 deletion lib/ZuluIDE_platform_RP2040/rp2040_sdio.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ sdio_status_t rp2040_sdio_command_R3(uint8_t command, uint32_t arg, uint32_t *re

// Start transferring data from SD card to memory buffer
// Transfer block size is always 512 bytes.
sdio_status_t rp2040_sdio_rx_start(uint8_t *buffer, uint32_t num_blocks);
sdio_status_t rp2040_sdio_rx_start(uint8_t *buffer, uint32_t num_blocks, uint32_t block_size = SDIO_BLOCK_SIZE);

// Check if reception is complete
// Returns SDIO_BUSY while transferring, SDIO_OK when done and error on failure.
Expand All @@ -69,5 +69,8 @@ sdio_status_t rp2040_sdio_tx_poll(uint32_t *bytes_complete = nullptr);
// Force everything to idle state
sdio_status_t rp2040_sdio_stop();

// Receives the SD Status register. Does not return until the register has been received.
sdio_status_t receive_status_register(uint8_t* sds);

// (Re)initialize the SDIO interface
void rp2040_sdio_init(int clock_divider = 1);
21 changes: 20 additions & 1 deletion lib/ZuluIDE_platform_RP2040/sd_card_sdio.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/**
* ZuluIDE™ - Copyright (c) 2023 Rabbit Hole Computing™
* ZuluIDE™ - Copyright (c) 2023-2024 Rabbit Hole Computing™
* Copyright (c) 2024 Tech by Androda, LLC
*
* ZuluIDE™ firmware is licensed under the GPL version 3 or any later version. 
*
Expand Down Expand Up @@ -35,6 +36,7 @@ static uint32_t g_sdio_ocr; // Operating condition register from card
static uint32_t g_sdio_rca; // Relative card address
static cid_t g_sdio_cid;
static csd_t g_sdio_csd;
static sds_t __attribute__((aligned(4))) g_sdio_sds;
static int g_sdio_error_line;
static sdio_status_t g_sdio_error;
static uint32_t g_sdio_dma_buf[128];
Expand Down Expand Up @@ -167,6 +169,17 @@ bool SdioCard::begin(SdioConfig sdioConfig)
return false;
}

// Read SD Status field
memset(&g_sdio_sds, 0, sizeof(sds_t));
uint8_t* stat_pointer = (uint8_t*) &g_sdio_sds;
if (!checkReturnOk(rp2040_sdio_command_R1(CMD55, g_sdio_rca, &reply)) ||
!checkReturnOk(rp2040_sdio_command_R1(ACMD13, 0, &reply)) ||
!checkReturnOk(receive_status_register(stat_pointer)))
{
dbgmsg("SDIO failed to get SD Status");
return false;
}

// Increase to 25 MHz clock rate
rp2040_sdio_init(1);

Expand Down Expand Up @@ -210,6 +223,12 @@ bool SdioCard::readCSD(csd_t* csd)
return true;
}

bool SdioCard::readSDS(sds_t* sds)
{
*sds = g_sdio_sds;
return true;
}

bool SdioCard::readOCR(uint32_t* ocr)
{
// SDIO mode does not have CMD58, but main program uses this to
Expand Down
2 changes: 1 addition & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ extra_scripts = src/build_bootloader.py
board_build.ldscript = lib/ZuluIDE_platform_RP2040/rp2040.ld
ldscript_bootloader = lib/ZuluIDE_platform_RP2040/rp2040_btldr.ld
lib_deps =
SdFat=https://github.com/rabbitholecomputing/SdFat#2.2.0-gpt
SdFat=https://github.com/rabbitholecomputing/SdFat#2.2.3-gpt
minIni
ZuluControl
CUEParser=https://github.com/rabbitholecomputing/CUEParser
Expand Down
9 changes: 9 additions & 0 deletions src/ZuluIDE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ void status_observer(const zuluide::status::SystemStatus& current);
void loadFirstImage();
void load_image(const zuluide::images::Image& toLoad, bool insert = true);

#define SD_SPEED_CLASS_WARN_BELOW 10

/************************************/
/* Status reporting by blinking led */
/************************************/
Expand Down Expand Up @@ -172,6 +174,13 @@ void print_sd_info()
logmsg("SD Date: ", (int)sd_cid.mdtMonth(), "/", sd_cid.mdtYear());
logmsg("SD Serial: ", sd_cid.psn());
}

sds_t sds = {0};
SD.card()->readSDS(&sds);
if ( sds.speedClass() < SD_SPEED_CLASS_WARN_BELOW)
{
logmsg("WARNING: Your SD Card Speed Class is ", (int)sds.speedClass(), ". Class ", (int) SD_SPEED_CLASS_WARN_BELOW," or better is recommended for best performance.");
}
}


Expand Down
2 changes: 1 addition & 1 deletion src/ZuluIDE_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#include <ZuluIDE_platform.h>

// Use variables for version number
#define FW_VER_NUM "2024.09.17"
#define FW_VER_NUM "2024.10.04"
#define FW_VER_SUFFIX "devel"
#define ZULU_FW_VERSION FW_VER_NUM "-" FW_VER_SUFFIX

Expand Down
1 change: 0 additions & 1 deletion src/ide_imagefile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,6 @@ bool IDEImageFile::write(uint64_t startpos, size_t blocksize, size_t num_blocks,
sd_cb_state.blocks_available = 0;
sd_cb_state.bufsize_blocks = m_buffer_size / blocksize;

bool first_run = true;
while (sd_cb_state.blocks_done < num_blocks && !sd_cb_state.error)
{
platform_poll();
Expand Down
12 changes: 0 additions & 12 deletions src/ide_rigid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,6 @@
extern uint8_t g_ide_signals;
static uint8_t ide_disk_buffer[512];

// Map from command index for command name for logging
static const char *get_atapi_command_name(uint8_t cmd)
{
switch (cmd)
{
#define CMD_NAME_TO_STR(name, code) case code: return #name;
ATAPI_COMMAND_LIST(CMD_NAME_TO_STR)
#undef CMD_NAME_TO_STR
default: return "UNKNOWN_CMD";
}
}

static bool find_chs_capacity(uint64_t lba, uint16_t max_cylinders, uint8_t min_heads, uint16_t &c, uint8_t &h, uint8_t &s)
{
bool found_chs = false;
Expand Down

0 comments on commit 7996923

Please sign in to comment.