From b4a3f2038d236048a64161f2112ed36cce29b063 Mon Sep 17 00:00:00 2001 From: bsongis Date: Tue, 22 May 2012 18:24:48 +0000 Subject: [PATCH] Some SD-card work for the ARM board (high level) --- src/eeprom_arm.cpp | 128 ++++++++++++++++++++++- src/eeprom_arm.h | 5 + src/eeprom_avr.cpp | 2 +- src/eeprom_avr.h | 2 +- src/ersky9x/diskio.cpp | 225 ++++++++++++++++++++++------------------- src/ersky9x/diskio.h | 1 - src/gruvin9x/logs.cpp | 10 +- src/gruvin9x/sdcard.h | 11 +- 8 files changed, 268 insertions(+), 116 deletions(-) diff --git a/src/eeprom_arm.cpp b/src/eeprom_arm.cpp index da11048ef..c54ff81b3 100644 --- a/src/eeprom_arm.cpp +++ b/src/eeprom_arm.cpp @@ -496,7 +496,7 @@ void eeLoadModel(uint8_t id) resetProto(); resetAll(); -#ifdef SDCARD +#if defined(SDCARD) && defined(PCBV4) initLogs(); #endif } @@ -904,3 +904,129 @@ uint32_t unprotect_eeprom() return spi_operation( p, Spi_rx_buf, 4 ) ; } +#if defined(SDCARD) +FATFS g_FATFS_Obj; // TODO not here +const pm_char * eeBackupModel(uint8_t i_fileSrc) +{ + char *buf = reusableBuffer.models.mainname; + FIL archiveFile; + DIR archiveFolder; + UINT written; + + FRESULT result = f_mount(0, &g_FATFS_Obj); + if (result != FR_OK) { + return SDCARD_ERROR(result); + } + + // check and create folder here + strcpy(buf, STR_MODELS_PATH); + result = f_opendir(&archiveFolder, buf); + if (result != FR_OK) { + result = f_mkdir(buf); + if (result != FR_OK) + return SDCARD_ERROR(result); + } + + buf[sizeof(MODELS_PATH)-1] = '/'; + memcpy(&buf[sizeof(MODELS_PATH)], ModelNames[i_fileSrc], sizeof(g_model.name)); + buf[sizeof(MODELS_PATH)+sizeof(g_model.name)] = '\0'; + + uint8_t i = sizeof(MODELS_PATH)+sizeof(g_model.name)-1; + uint8_t len = 0; + while (i>sizeof(MODELS_PATH)-1) { + if (!len && buf[i]) + len = i+1; + if (len) + buf[i] = idx2char(buf[i]); + i--; + } + + if (len == 0) { + uint8_t num = i_fileSrc + 1; + strcpy(&buf[sizeof(MODELS_PATH)], STR_MODEL); + buf[sizeof(MODELS_PATH) + PSIZE(TR_MODEL)] = (char)((num / 10) + '0'); + buf[sizeof(MODELS_PATH) + PSIZE(TR_MODEL) + 1] = (char)((num % 10) + '0'); + len = sizeof(MODELS_PATH) + PSIZE(TR_MODEL) + 2; + } + + strcpy(&buf[len], STR_MODELS_EXT); + + result = f_open(&archiveFile, buf, FA_OPEN_ALWAYS | FA_WRITE); + if (result != FR_OK) { + return SDCARD_ERROR(result); + } + + result = f_write(&archiveFile, &g_eeGeneral.myVers, 1, &written); + if (result != FR_OK) { + return SDCARD_ERROR(result); + } + + uint16_t size = File_system[i_fileSrc].size ; + read32_eeprom_data( (File_system[i_fileSrc+1].block_no << 12) + sizeof( struct t_eeprom_header), ( uint8_t *)&Eeprom_buffer.data.model_data, size) ; + + result = f_write(&archiveFile, (uint8_t *)&Eeprom_buffer.data.model_data, size, &written); + if (result != FR_OK) { + return SDCARD_ERROR(result); + } + + f_close(&archiveFile); + + return NULL; +} + +const pm_char * eeRestoreModel(uint8_t i_fileDst, char *model_name) +{ + char *buf = reusableBuffer.models.mainname; + FIL restoreFile; + UINT read; + + FRESULT result = f_mount(0, &g_FATFS_Obj); + if (result != FR_OK) { + return SDCARD_ERROR(result); + } + + strcpy(buf, STR_MODELS_PATH); + buf[sizeof(MODELS_PATH)-1] = '/'; + strcpy(&buf[sizeof(MODELS_PATH)], model_name); + strcpy(&buf[strlen(buf)], STR_MODELS_EXT); + + result = f_open(&restoreFile, buf, FA_OPEN_EXISTING | FA_READ); + if (result != FR_OK) { + return SDCARD_ERROR(result); + } + + result = f_read(&restoreFile, (uint8_t *)buf, 1, &read); + if (result != FR_OK || read != 1) { + return SDCARD_ERROR(result); + } + + if (buf[0] != g_eeGeneral.myVers) { + // TODO + } + + if (eeModelExists(i_fileDst)) { + eeDeleteModel(i_fileDst); + } + + result = f_read(&restoreFile, ( uint8_t *)&Eeprom_buffer.data.model_data, sizeof(g_model), &read); + f_close(&restoreFile); + + if (result != FR_OK) { + return SDCARD_ERROR(result); + } + + // TODO flash saving ... + if (read > sizeof(g_model.name)) + memcpy(ModelNames[i_fileDst], Eeprom_buffer.data.model_data.name, sizeof(g_model.name)); + else + memset(ModelNames[i_fileDst], 0, sizeof(g_model.name)); + + Eeprom32_source_address = (uint8_t *)&Eeprom_buffer.data.model_data; // Get data from here + Eeprom32_data_size = sizeof(g_model) ; // This much + Eeprom32_file_index = i_fileDst + 1 ; // This file system entry + Eeprom32_process_state = E32_BLANKCHECK ; + eeWaitFinished(); + + return NULL; +} +#endif diff --git a/src/eeprom_arm.h b/src/eeprom_arm.h index 11a1bc9a1..fa57009f0 100644 --- a/src/eeprom_arm.h +++ b/src/eeprom_arm.h @@ -73,5 +73,10 @@ extern ModelData g_model; extern uint8_t Spi_tx_buf[] ; extern uint8_t Spi_rx_buf[] ; +#if defined(SDCARD) +const pm_char * eeBackupModel(uint8_t i_fileSrc); +const pm_char * eeRestoreModel(uint8_t i_fileDst, char *model_name); +#endif + #endif diff --git a/src/eeprom_avr.cpp b/src/eeprom_avr.cpp index 2af6cd01d..4660d4bad 100644 --- a/src/eeprom_avr.cpp +++ b/src/eeprom_avr.cpp @@ -630,7 +630,7 @@ const pm_char * eeRestoreModel(uint8_t i_fileDst, char *model_name) // TODO } - if (EFile::exists(FILE_MODEL(i_fileDst))) { + if (eeModelExists(i_fileDst)) { eeDeleteModel(i_fileDst); } diff --git a/src/eeprom_avr.h b/src/eeprom_avr.h index f184b0757..9c3dded96 100644 --- a/src/eeprom_avr.h +++ b/src/eeprom_avr.h @@ -214,7 +214,7 @@ uint16_t evalChkSum(); #define eeCopyModel(dst, src) theFile.copy(FILE_MODEL(dst), FILE_MODEL(src)) #define eeSwapModels(id1, id2) EFile::swap(FILE_MODEL(id1), FILE_MODEL(id2)) -#ifdef SDCARD +#if defined(SDCARD) const pm_char * eeBackupModel(uint8_t i_fileSrc); const pm_char * eeRestoreModel(uint8_t i_fileDst, char *model_name); #endif diff --git a/src/ersky9x/diskio.cpp b/src/ersky9x/diskio.cpp index 360252534..55917af6a 100644 --- a/src/ersky9x/diskio.cpp +++ b/src/ersky9x/diskio.cpp @@ -248,7 +248,7 @@ void sd_cmd55() uint32_t sd_acmd41() { uint32_t i ; - Hsmci *phsmci = HSMCI ; + Hsmci *phsmci = HSMCI ; if ( CardIsConnected() ) { @@ -275,7 +275,7 @@ uint32_t sd_acmd41() uint32_t sd_cmd2() { uint32_t i ; - Hsmci *phsmci = HSMCI ; + Hsmci *phsmci = HSMCI ; if ( CardIsConnected() ) { @@ -305,7 +305,7 @@ uint32_t sd_cmd2() uint32_t sd_cmd3() { uint32_t i ; - Hsmci *phsmci = HSMCI ; + Hsmci *phsmci = HSMCI ; if ( CardIsConnected() ) { @@ -331,7 +331,7 @@ uint32_t sd_cmd3() uint32_t sd_cmd9() { uint32_t i ; - Hsmci *phsmci = HSMCI ; + Hsmci *phsmci = HSMCI ; if ( CardIsConnected() ) { @@ -361,7 +361,7 @@ uint32_t sd_cmd9() uint32_t sd_cmd7() { uint32_t i ; - Hsmci *phsmci = HSMCI ; + Hsmci *phsmci = HSMCI ; if ( CardIsConnected() ) { @@ -383,11 +383,11 @@ uint32_t sd_cmd7() } } -#define HSMCI_CMDR_SPCMD_STD ( 0 << 8 ) -#define HSMCI_CMDR_RSPTYP_48_BIT ( 1 << 6 ) +#define HSMCI_CMDR_SPCMD_STD ( 0 << 8 ) +#define HSMCI_CMDR_RSPTYP_48_BIT ( 1 << 6 ) #define HSMCI_CMDR_TRCMD_START_DATA ( 1 << 16 ) -#define HSMCI_CMDR_TRDIR_READ ( 1 << 18 ) -#define HSMCI_CMDR_TRTYP_SINGLE ( 0 << 19 ) +#define HSMCI_CMDR_TRDIR_READ ( 1 << 18 ) +#define HSMCI_CMDR_TRTYP_SINGLE ( 0 << 19 ) #define SD_SEND_SCR (51 | HSMCI_CMDR_SPCMD_STD | HSMCI_CMDR_RSPTYP_48_BIT \ | HSMCI_CMDR_TRCMD_START_DATA | HSMCI_CMDR_TRDIR_READ \ @@ -395,14 +395,18 @@ uint32_t sd_cmd7() #define SD_READ_SINGLE_BLOCK (17 | HSMCI_CMDR_SPCMD_STD | HSMCI_CMDR_RSPTYP_48_BIT \ | HSMCI_CMDR_TRCMD_START_DATA | HSMCI_CMDR_TRDIR_READ \ - | HSMCI_CMDR_TRTYP_SINGLE | HSMCI_CMDR_MAXLAT) + | HSMCI_CMDR_TRTYP_SINGLE | HSMCI_CMDR_MAXLAT) + +#define SD_WRITE_SINGLE_BLOCK (17 | HSMCI_CMDR_SPCMD_STD | HSMCI_CMDR_RSPTYP_48_BIT \ + | HSMCI_CMDR_TRCMD_START_DATA | HSMCI_CMDR_TRDIR_READ \ + | HSMCI_CMDR_TRTYP_SINGLE | HSMCI_CMDR_MAXLAT) // Get SCR uint32_t sd_acmd51( uint32_t *presult ) { uint32_t i ; uint32_t j = 0 ; - Hsmci *phsmci = HSMCI ; + Hsmci *phsmci = HSMCI ; if ( CardIsConnected() ) { @@ -473,45 +477,6 @@ uint32_t sd_acmd6() } } - -// Read SD card from (byte) address, for 512 bytes -uint32_t sd_cmd17( uint32_t address, uint32_t *presult ) -{ - uint32_t i ; - uint32_t j = 0 ; - Hsmci *phsmci = HSMCI ; - - if ( CardIsConnected() ) - { - // Block size = 512, nblocks = 1 - phsmci->HSMCI_BLKR = ( ( 512 ) << 16 ) | 1 ; - phsmci->HSMCI_ARGR = address ; - phsmci->HSMCI_CMDR = SD_READ_SINGLE_BLOCK ; - - for ( i = 0 ; i < 50000 ; i += 1 ) - { - if ( phsmci->HSMCI_SR & HSMCI_SR_RXRDY ) - { - *presult++ = phsmci->HSMCI_RDR ; - j += 1 ; - } - if ( ( phsmci->HSMCI_SR & ( HSMCI_SR_CMDRDY | HSMCI_SR_XFRDONE ) ) == ( HSMCI_SR_CMDRDY | HSMCI_SR_XFRDONE ) ) - { - break ; - } - if ( j >= 128 ) - { - break ; - } - } - return i | (j << 16) ; //phsmci->HSMCI_RSPR[0] ; - } - else - { - return 0 ; - } -} - // This routine is called every 10 mS, and checks for card // insertion and removal. // When a card is inserted, it initialises it ready for read/write access. @@ -606,7 +571,39 @@ uint32_t sd_read_block( uint32_t block_no, uint32_t *data ) { if ( Card_state == SD_ST_DATA ) { - return sd_cmd17( block_no << 9, data ) ; + uint32_t i ; + uint32_t j = 0 ; + Hsmci *phsmci = HSMCI ; + + if ( CardIsConnected() ) + { + // Block size = 512, nblocks = 1 + phsmci->HSMCI_BLKR = ( ( 512 ) << 16 ) | 1 ; + phsmci->HSMCI_ARGR = block_no << 9 ; + phsmci->HSMCI_CMDR = SD_READ_SINGLE_BLOCK ; + + for ( i = 0 ; i < 50000 ; i += 1 ) + { + if ( phsmci->HSMCI_SR & HSMCI_SR_RXRDY ) + { + *data++ = phsmci->HSMCI_RDR ; + j += 1 ; + } + if ( ( phsmci->HSMCI_SR & ( HSMCI_SR_CMDRDY | HSMCI_SR_XFRDONE ) ) == ( HSMCI_SR_CMDRDY | HSMCI_SR_XFRDONE ) ) + { + break ; + } + if ( j >= 128 ) + { + break ; + } + } + return i | (j << 16) ; //phsmci->HSMCI_RSPR[0] ; + } + else + { + return 0 ; + } } else { @@ -614,6 +611,50 @@ uint32_t sd_read_block( uint32_t block_no, uint32_t *data ) } } +uint32_t sd_write_block( uint32_t block_no, uint32_t *data ) +{ + if ( Card_state == SD_ST_DATA ) + { + uint32_t i ; + uint32_t j = 0 ; + Hsmci *phsmci = HSMCI ; + + if ( CardIsConnected() ) + { + // Block size = 512, nblocks = 1 + phsmci->HSMCI_BLKR = ( ( 512 ) << 16 ) | 1 ; + phsmci->HSMCI_ARGR = block_no << 9 ; + phsmci->HSMCI_CMDR = SD_WRITE_SINGLE_BLOCK ; +#if 0 + for ( i = 0 ; i < 50000 ; i += 1 ) + { + if ( phsmci->HSMCI_SR & HSMCI_SR_RXRDY ) + { + *data++ = phsmci->HSMCI_RDR ; + j += 1 ; + } + if ( ( phsmci->HSMCI_SR & ( HSMCI_SR_CMDRDY | HSMCI_SR_XFRDONE ) ) == ( HSMCI_SR_CMDRDY | HSMCI_SR_XFRDONE ) ) + { + break ; + } + if ( j >= 128 ) + { + break ; + } + } +#endif + return i | (j << 16) ; //phsmci->HSMCI_RSPR[0] ; + } + else + { + return 0 ; + } + } + else + { + return 0 ; + } +} /* Notes on SD card: @@ -799,38 +840,23 @@ DRESULT disk_read ( if ( sd_card_ready() == 0 ) return RES_NOTRDY; - if (count == 1) - { /* Single block read */ - result = sd_read_block( sector, ( uint32_t *)buff ) ; - if ( result ) - { - count = 0 ; - } -// if ((send_cmd(CMD17, sector) == 0) /* READ_SINGLE_BLOCK */ -// && rcvr_datablock(buff, 512)) -// count = 0; - } - else - { /* Multiple block read */ - do - { - result = sd_read_block( sector, ( uint32_t *)buff ) ; - if ( result ) - { - sector += 1 ; - buff += 512 ; - count -= 1 ; - } - else - { - count = 1 ; // Flag error - break ; - } - } while ( count ) ; - } + do { + result = sd_read_block( sector, ( uint32_t *)buff ) ; + if (result) { + sector += 1 ; + buff += 512 ; + count -= 1 ; + } + else { + count = 1 ; // Flag error + break ; + } + } while ( count ) ; + return count ? RES_ERROR : RES_OK; } + /*-----------------------------------------------------------------------*/ /* Write Sector(s) */ /*-----------------------------------------------------------------------*/ @@ -842,32 +868,27 @@ DRESULT disk_write ( BYTE count /* Sector count (1..255) */ ) { + uint32_t result ; + if (drv || !count) return RES_PARERR; -#if 0 - if (Stat & STA_NOINIT) return RES_NOTRDY; - if (Stat & STA_PROTECT) return RES_WRPRT; + if ( sd_card_ready() == 0 ) return RES_NOTRDY; - if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */ + // TODO if (Stat & STA_PROTECT) return RES_WRPRT; + + do { + result = sd_write_block( sector, ( uint32_t *)buff ) ; + if (result) { + sector += 1 ; + buff += 512 ; + count -= 1 ; + } + else { + count = 1 ; // Flag error + break ; + } + } while ( count ) ; - if (count == 1) { /* Single block write */ - if ((send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */ - && xmit_datablock(buff, 0xFE)) - count = 0; - } - else { /* Multiple block write */ - if (CardType & CT_SDC) send_cmd(ACMD23, count); - if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */ - do { - if (!xmit_datablock(buff, 0xFC)) break; - buff += 512; - } while (--count); - if (!xmit_datablock(0, 0xFD)) /* STOP_TRAN token */ - count = 1; - } - } - deselect(); -#endif return count ? RES_ERROR : RES_OK; } diff --git a/src/ersky9x/diskio.h b/src/ersky9x/diskio.h index ce0ddf093..fa029a975 100644 --- a/src/ersky9x/diskio.h +++ b/src/ersky9x/diskio.h @@ -134,7 +134,6 @@ extern uint32_t sd_cmd2( void ) ; extern uint32_t sd_cmd3( void ) ; extern uint32_t sd_cmd7( void ) ; extern uint32_t sd_cmd9( void ) ; -extern uint32_t sd_cmd17( uint32_t address, uint32_t *presult ) ; extern uint32_t sd_acmd6( void ) ; extern uint32_t sd_acmd51( uint32_t *presult ) ; extern void sd_poll_10mS( void ) ; diff --git a/src/gruvin9x/logs.cpp b/src/gruvin9x/logs.cpp index a0e8dcc42..1a87cac72 100644 --- a/src/gruvin9x/logs.cpp +++ b/src/gruvin9x/logs.cpp @@ -35,7 +35,7 @@ #include "ff.h" char g_logFilename[21]; // "/O9XLOGS/M00_000.CSV\0" max required length = 21 -FATFS g_FATFS_Obj; +FATFS g_FATFS_Obj; // TODO not here FIL g_oLogFile; int8_t g_logState = 0; // 0=closed, >0=opened, <0=error const pm_char * g_logError = NULL; @@ -128,14 +128,6 @@ void initLogs() // g_logFilename should now be set appropriately. } -const pm_char *SDCARD_ERROR(FRESULT result) -{ - if (result == FR_NOT_READY) - return STR_NO_SDCARD; - else - return STR_SDCARD_ERROR; -} - void writeLogs() { FRESULT result; diff --git a/src/gruvin9x/sdcard.h b/src/gruvin9x/sdcard.h index c54c0ffca..028edeeda 100644 --- a/src/gruvin9x/sdcard.h +++ b/src/gruvin9x/sdcard.h @@ -35,7 +35,10 @@ #define sdcard_h #include "ff.h" +#if defined(PCBV4) +// TODO because this file is used for ersky9x #include "rtc.h" +#endif #include "gtime.h" #define LOGS_PATH "/9XLOGS" // no trailing slash = important @@ -50,7 +53,13 @@ extern FIL g_oLogFile; extern void initLogs(); extern void writeLogs(); -const pm_char *SDCARD_ERROR(FRESULT result); +const pm_char *SDCARD_ERROR(FRESULT result) +{ + if (result == FR_NOT_READY) + return STR_NO_SDCARD; + else + return STR_SDCARD_ERROR; +} // MM/SD card Disk IO Support extern void disk_timerproc(void);