From 598705c7fad2f6dc9d448a37d0c9df1df7bdadd1 Mon Sep 17 00:00:00 2001 From: Ari Sundholm Date: Thu, 5 Nov 2020 18:52:09 +0200 Subject: [PATCH] ulibSD/sd_io.c: Fix writing to SD card. There were a few things wrong with the SD card write implementation: 1. The protocol change regarding the interpretation of offsets introduced with SDHC cards was not taken into account in the write path, unlike in the read path. 2. All SPI writes involved in the process were actually issued as reads due to the use of the SPI_RW() function, the implementation of which seems to have gone through some churn. Likely just an instance of bit-rot. --- software/sys_controller/ulibSD/sd_io.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/software/sys_controller/ulibSD/sd_io.c b/software/sys_controller/ulibSD/sd_io.c index da04a49..6c33c42 100644 --- a/software/sys_controller/ulibSD/sd_io.c +++ b/software/sys_controller/ulibSD/sd_io.c @@ -160,15 +160,15 @@ SDRESULTS __SD_Write_Block(SD_DEV *dev, void *dat, BYTE token) WORD idx; BYTE line; // Send token (single or multiple) - SPI_RW(token); + SPI_WW(token); // Single block write? if(token != 0xFD) { // Send block data - for(idx=0; idx!=SD_BLK_SIZE; idx++) SPI_RW(*((BYTE*)dat + idx)); + for(idx=0; idx!=SD_BLK_SIZE; idx++) SPI_WW(*((BYTE*)dat + idx)); /* Dummy CRC */ - SPI_RW(0xFF); - SPI_RW(0xFF); + SPI_WW(0xFF); + SPI_WW(0xFF); // If not accepted, returns the reject error if((SPI_RW(0xFF) & 0x1F) != 0x05) return(SD_REJECT); } @@ -447,9 +447,13 @@ SDRESULTS SD_Write(SD_DEV *dev, void *dat, DWORD sector) #else // uControllers // Query ok? if(sector > dev->last_sector) return(SD_PARERR); + // Convert sector number to byte address (sector * SD_BLK_SIZE) for SDC1 + if (!(dev->cardtype & SDCT_BLOCK)) + sector *= SD_BLK_SIZE; + // Single block write (token <- 0xFE) // Convert sector number to bytes address (sector * SD_BLK_SIZE) - if(__SD_Send_Cmd(CMD24, sector * SD_BLK_SIZE)==0) + if(__SD_Send_Cmd(CMD24, sector)==0) return(__SD_Write_Block(dev, dat, 0xFE)); else return(SD_ERROR);