diff --git a/fatfs/shimatta_sdio_driver/shimatta_sdio.c b/fatfs/shimatta_sdio_driver/shimatta_sdio.c index 7386221..ebf48a5 100644 --- a/fatfs/shimatta_sdio_driver/shimatta_sdio.c +++ b/fatfs/shimatta_sdio_driver/shimatta_sdio.c @@ -181,10 +181,10 @@ static int sdio_send_csd_cmd9(uint16_t rca, uint32_t *response_buffer) { /** * @brief Send data buffer to SD card * @param dlen Data length. Must be a multiple of 4 bytes - * @param blklen Block length + * @param blklen Log2 of block length (9 in case of 512 byte block) * @param buff Buffer to send */ -static void sdio_write_buffer(uint32_t dlen, uint32_t blklen, uint8_t *buff) +static void sdio_write_buffer(uint32_t dlen, uint32_t log_blklen, const unsigned char *buff) { uint32_t count; int byte_count; @@ -197,7 +197,7 @@ static void sdio_write_buffer(uint32_t dlen, uint32_t blklen, uint8_t *buff) SDIO->ICR = SDIO_ICR_CCRCFAILC | SDIO_ICR_DCRCFAILC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_DTIMEOUTC | SDIO_ICR_TXUNDERRC | SDIO_ICR_RXOVERRC | SDIO_ICR_CMDRENDC | SDIO_ICR_CMDSENTC | SDIO_ICR_DATAENDC | SDIO_ICR_STBITERRC | SDIO_ICR_DBCKENDC | SDIO_ICR_SDIOITC | SDIO_ICR_CEATAENDC; - SDIO->DCTRL = (blklen<<4) | SDIO_DCTRL_DTEN; + SDIO->DCTRL = (log_blklen<<4) | SDIO_DCTRL_DTEN; for (count = 0; count < dlen; count += 4) { fifo = 0; @@ -225,9 +225,11 @@ static void sdio_write_buffer(uint32_t dlen, uint32_t blklen, uint8_t *buff) static int sdio_send_write_block_cmd24(uint32_t addr) { - (void)addr; + uint32_t response; - return -1; + sdio_send_cmd(24, addr, SHORT_ANS); + + return sdio_get_response(24, SHORT_ANS, &response); } static int sdio_check_status_register_cmd13(uint16_t rca, uint32_t *status) @@ -691,5 +693,41 @@ DRESULT sdio_disk_read(BYTE *buff, DWORD sector, UINT count){ */ DRESULT sdio_disk_write(const BYTE *buff, DWORD sector, UINT count) { - return RES_ERROR; + uint32_t addr; + union sdio_status_conv status; + uint32_t buff_offset = 0; + int ret; + + if (sdio_check_write_protection()) + return RES_WRPRT; + + addr = (card_info.type == SD_V2_HC ? (sector) : (sector * 512)); + + while (count) { + do { + sdio_check_status_register_cmd13(card_info.rca, &status.value); + } while (status.statusstruct.CURRENT_STATE == CURRENT_STATE_PRG || + status.statusstruct.CURRENT_STATE == CURRENT_STATE_RCV); + + if (status.statusstruct.CURRENT_STATE == CURRENT_STATE_STBY) { + if (sdio_send_select_card_cmd7(card_info.rca)) + return RES_ERROR; + } + + do { + sdio_check_status_register_cmd13(card_info.rca, &status.value); + } while (status.statusstruct.READY_FOR_DATA != 1); + + ret = sdio_send_write_block_cmd24(addr); + if (ret) { + return RES_ERROR; + } + sdio_write_buffer(512, 9, &buff[buff_offset]); + + buff_offset += 512; + addr += (card_info.type == SD_V2_HC ? 1 : 512); + count--; + } + + return RES_OK; } diff --git a/include/fatfs/ffconf.h b/include/fatfs/ffconf.h index 3145b9b..926378a 100644 --- a/include/fatfs/ffconf.h +++ b/include/fatfs/ffconf.h @@ -8,7 +8,7 @@ / Function Configurations /---------------------------------------------------------------------------*/ -#define FF_FS_READONLY 1 +#define FF_FS_READONLY 0 /* This option switches read-only configuration. (0:Read/Write or 1:Read-only) / Read-only configuration removes writing API functions, f_write(), f_sync(), / f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree() diff --git a/main.c b/main.c index afc193a..95eb545 100644 --- a/main.c +++ b/main.c @@ -26,6 +26,8 @@ int main() { char buff[1024]; char *name; FILINFO fno; + char *write_string = "This is a write test. Okay... Writing seems to work. Let's close the file\n"; + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; __DSB(); GPIOA->MODER |= OUTPUT(6) | OUTPUT(7); @@ -53,6 +55,13 @@ int main() { } } + + initreq = f_open(&file, "foo.txt", FA_OPEN_APPEND | FA_WRITE); + if (initreq == FR_OK) { + initreq = f_write(&file, write_string, strlen(write_string), NULL); + initreq = f_close(&file); + } + //fflush(stdout); while(1);