From 25677ae79aa7609b50bf03ce73b1deb4d4441423 Mon Sep 17 00:00:00 2001 From: Shirait Date: Tue, 5 Jun 2007 06:32:50 +0000 Subject: [PATCH] =?UTF-8?q?Thread=E4=B8=8D=E4=BD=BF=E7=94=A8=E7=89=88SD?= =?UTF-8?q?=E3=83=89=E3=83=A9=E3=82=A4=E3=83=90=E8=BF=BD=E5=8A=A0=E3=80=81?= =?UTF-8?q?=E3=82=B5=E3=83=B3=E3=83=97=E3=83=AB=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/twl_wrapsdk/trunk@102 4ee2a332-4b2b-5046-8439-1ba90f034370 --- build/libraries/Makefile | 1 + build/libraries/devices/Makefile | 1 + .../libraries/devices/rom_sdmc/ARM7/Makefile | 66 + .../libraries/devices/rom_sdmc/ARM7/drsdmc.c | 686 +++++ build/libraries/devices/rom_sdmc/ARM7/sdif.c | 1188 ++++++++ .../libraries/devices/rom_sdmc/ARM7/sdif_ip.h | 349 +++ .../devices/rom_sdmc/ARM7/sdif_reg.h | 118 + build/libraries/devices/rom_sdmc/ARM7/sdmc.c | 2529 +++++++++++++++++ .../devices/rom_sdmc/ARM7/sdmc_config.h | 85 + build/libraries/devices/rom_sdmc/Makefile | 34 + build/libraries/devices/sdmc/ARM7/sdif_reg.h | 19 +- build/libraries/devices/sdmc/ARM7/sdmc.c | 164 +- build/libraries/fatfs/ARM7/Makefile | 1 - build/tests/fatfs/Makefile | 31 + build/tests/fatfs/fatfs_sd/ARM7/Makefile | 53 + build/tests/fatfs/fatfs_sd/ARM7/main.lsf | 40 + build/tests/fatfs/fatfs_sd/ARM7/src/main.c | 239 ++ build/tests/fatfs/fatfs_sd/Makefile | 32 + 18 files changed, 5566 insertions(+), 70 deletions(-) create mode 100644 build/libraries/devices/rom_sdmc/ARM7/Makefile create mode 100644 build/libraries/devices/rom_sdmc/ARM7/drsdmc.c create mode 100644 build/libraries/devices/rom_sdmc/ARM7/sdif.c create mode 100644 build/libraries/devices/rom_sdmc/ARM7/sdif_ip.h create mode 100644 build/libraries/devices/rom_sdmc/ARM7/sdif_reg.h create mode 100644 build/libraries/devices/rom_sdmc/ARM7/sdmc.c create mode 100644 build/libraries/devices/rom_sdmc/ARM7/sdmc_config.h create mode 100644 build/libraries/devices/rom_sdmc/Makefile create mode 100644 build/tests/fatfs/Makefile create mode 100644 build/tests/fatfs/fatfs_sd/ARM7/Makefile create mode 100644 build/tests/fatfs/fatfs_sd/ARM7/main.lsf create mode 100644 build/tests/fatfs/fatfs_sd/ARM7/src/main.c create mode 100644 build/tests/fatfs/fatfs_sd/Makefile diff --git a/build/libraries/Makefile b/build/libraries/Makefile index c836c95..c7101f2 100644 --- a/build/libraries/Makefile +++ b/build/libraries/Makefile @@ -33,6 +33,7 @@ SUBDIRS = \ cdc \ snd \ camera \ + devices \ #---------------------------------------------------------------------------- export NITRO_BLXCHECKED = yes diff --git a/build/libraries/devices/Makefile b/build/libraries/devices/Makefile index 73a8cd3..f6cba7c 100644 --- a/build/libraries/devices/Makefile +++ b/build/libraries/devices/Makefile @@ -22,6 +22,7 @@ include $(TWLSDK_ROOT)/build/buildtools/commondefs SUBDIRS = \ sdmc \ + rom_sdmc \ #---------------------------------------------------------------------------- export NITRO_BLXCHECKED = yes diff --git a/build/libraries/devices/rom_sdmc/ARM7/Makefile b/build/libraries/devices/rom_sdmc/ARM7/Makefile new file mode 100644 index 0000000..9b8fd56 --- /dev/null +++ b/build/libraries/devices/rom_sdmc/ARM7/Makefile @@ -0,0 +1,66 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: TwlSDK - libraries - mi/ARM7 +# File: Makefile +# +# Copyright 2007 Nintendo. All rights reserved. +# +# These coded instructions, statements, and computer programs contain +# proprietary information of Nintendo of America Inc. and/or Nintendo +# Company Ltd., and are protected by Federal copyright law. They may +# not be disclosed to third parties or copied or duplicated in any form, +# in whole or in part, without the prior written consent of Nintendo. +# +# $Log: $ +# $NoKeywords: $ +#---------------------------------------------------------------------------- + +SUBDIRS = + + +#---------------------------------------------------------------------------- + +# build ARM & THUMB libraries +TWL_CODEGEN_ALL ?= True + +# Codegen for sub processer +TWL_PROC = ARM7 + +SRCDIR = ../common/src src + +INCDIR = ../common +INCDIR += $(TWLSDK_ROOT)/include/twl \ + $(TWLSDK_ROOT)/include/twl/devices/rom_sdmc/ARM7 \ + $(TWLSDK_ROOT)/include/twl/fatfs/ARM7 \ + +SRCS = \ + sdmc.c \ + sdif.c \ + drsdmc.c + +TARGET_LIB = libromsd_sp$(TWL_LIBSUFFIX).a + + +#---------------------------------------------------------------------------- + +# DEBUG版ビルドの場合、RELEASE版でビルドして +# DEBUG版のライブラリを装います。 + +ifdef NITRO_DEBUG +NITRO_BUILD_TYPE = RELEASE +endif + +include $(TWLSDK_ROOT)/build/buildtools/commondefs + +INSTALL_TARGETS = $(TARGETS) +INSTALL_DIR = $(TWL_INSTALL_LIBDIR) + + +#---------------------------------------------------------------------------- + +do-build: $(TARGETS) + +include $(TWLSDK_ROOT)/build/buildtools/modulerules + + +#===== End of Makefile ===== diff --git a/build/libraries/devices/rom_sdmc/ARM7/drsdmc.c b/build/libraries/devices/rom_sdmc/ARM7/drsdmc.c new file mode 100644 index 0000000..81910fa --- /dev/null +++ b/build/libraries/devices/rom_sdmc/ARM7/drsdmc.c @@ -0,0 +1,686 @@ +/*---------------------------------------------------------------------------* + Project: CTR - rtfs interface for SD Memory Card + File: drsdmc.h + + Copyright 2006,2007 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + *---------------------------------------------------------------------------*/ + +#include +#include +//#if (INCLUDE_SD) + +#include "sdmc_config.h" +#include "sdmc.h" +#include "sdif_ip.h" +#include "sdif_reg.h" + +#if (SD_DEBUG_PRINT_ON == 1) + #if (CTR_DEF_ENVIRONMENT_DSEMU == 1) + #define PRINTDEBUG osTPrintf + #else + #include + #define PRINTDEBUG vlink_dos_printf + #endif +#else + #define PRINTDEBUG( ...) ((void)0) +#endif + + +#define NUM_SD_PAGES +#define SD_PAGE_SIZE + + +/*---------------------------------------------------------------------------* + extern変数 + *---------------------------------------------------------------------------*/ +//extern ER_ID sdmc_dtq_id; +//extern ER_ID sdmc_result_dtq_id; +extern void (*func_SDCARD_In)(void); /* カード挿入イベント用コールバック保存用 */ +extern void (*func_SDCARD_Out)(void); /* カード排出イベント用コールバック保存用 */ +extern volatile s16 SDCARD_OutFlag; /* カード排出発生判定フラグ */ + +extern int rtfs_first_stat_flag[26]; + +/*SDメモリカードのスペック構造体*/ +extern SdmcSpec sdmc_current_spec; + + +/*---------------------------------------------------------------------------* + extern関数 + *---------------------------------------------------------------------------*/ +extern SDMC_ERR_CODE sdmcGoIdle(void (*func1)(),void (*func2)()); + + +/*---------------------------------------------------------------------------* + static変数 + *---------------------------------------------------------------------------*/ +static int sdmc_drive_no; +void (*func_usr_sdmc_out)(void) = NULL; /* カード排出イベントのユーザコールバック */ + + +/*---------------------------------------------------------------------------* + static関数 + *---------------------------------------------------------------------------*/ +void i_sdmcRemovedIntr( void); +static void sdi_get_CHS_params( void); +static u32 sdi_get_ceil( u32 cval, u32 mval); +static void sdi_get_nom( void); +static void sdi_get_fatparams( void); +static void sdi_build_partition_table( void); + + +/*---------------------------------------------------------------------------* + Name: sdmcCheckMedia + + Description: MBRのシグネチャおよび + パーティションのフォーマット種別をチェックする + + Arguments: + + Returns: TRUE/FALSE + (FALSEなら pc_format_media が必要) + *---------------------------------------------------------------------------*/ +BOOL sdmcCheckMedia( void) +{ + u16 i; + SdmcResultInfo SdResult; + u8* bufp; + u32 buffer[512/4]; + u8 systemid; + + /**/ + if( sdmcReadFifo( buffer, 1, 0, NULL, &SdResult)) { + return( FALSE); + } + + bufp = (u8*)buffer; + + /* Check the Signature Word. */ + if( (bufp[510]!=0x55) || (bufp[511]!=0xAA)) { + return( FALSE); + } + /* Check the System ID of partition. */ + systemid = bufp[450]; + if( (systemid!=0x01) && (systemid!=0x04) && (systemid!=0x06) && + (systemid!=0x0B) && (systemid!=0x0C)) { + return( FALSE); + } + /* Check the System ID of unuse partitions. */ + for( i=1; i<4; i++) { + systemid = bufp[450+(16*i)]; + if( systemid != 0x00) { + return( FALSE); + } + } + /**/ + /*もっと厳密にチェックするならパーティション0開始位置の + 正当性も調べる*/ + return( TRUE); +} + + +/*---------------------------------------------------------------------------* + Name: sdmcRtfsIo + + Description: 上位層からのセクタリード/ライト要求を受ける + + Arguments: driveno : ドライブ番号 + block : 開始ブロック番号 + buffer : + count : ブロック数 + reading : リード要求時にTRUE + + Returns: TRUE/FALSE + *---------------------------------------------------------------------------*/ +BOOL sdmcRtfsIo( int driveno, dword block, void* buffer, word count, BOOLEAN reading) +{ + u16 result; + SdmcResultInfo SdResult; + + if( reading) { + PRINTDEBUG( "DEVCTL_IO_READ ... block:%x, count:%x -> buf:%x\n", block, count, buffer); + result = sdmcReadFifo( buffer, count, block, NULL, &SdResult); +// result = sdmcRead( buffer, count, block, NULL, &SdResult); + }else{ + PRINTDEBUG( "DEVCTL_IO_WRITE ... block:%x, count:%x <- buf:%x\n", block, count, buffer); + result = sdmcWriteFifo( buffer, count, block, NULL, &SdResult); +// result = sdmcWrite( buffer, count, block, NULL, &SdResult); + } + if( result) { + return FALSE; + } + + return TRUE; +} + +/*---------------------------------------------------------------------------* + Name: sdmcRtfsCtrl + + Description: 上位層からのコントロール要求を受ける + + Arguments: driveno : ドライブ番号 + opcode : 要求の種類 + pargs : + + Returns: + Memo : DRIVE_FLAGS_REMOVABLEの場合、ドライバのIO関数を呼ぶ前に + CTRL関数のDEVCTL_CHECK_STATUSが呼ばれる。 + DEVTEST_CHANGED→DEVTEST_NOCHANGEが確認されるとRTFSはセクタ0を + 読みに行き、FATパラメータを取得した上で目的のセクタを読みに行く。 + CTRL関数の前にはDEVCTL_CHECK_STATUSが呼ばれないので、DEVCTL_ + GET_GEOMETRYでは自前で再挿入をチェックする必要がある。 + *---------------------------------------------------------------------------*/ +int sdmcRtfsCtrl( int driveno, int opcode, void* pargs) +{ + DDRIVE *pdr; + DEV_GEOMETRY gc; + int heads, secptrack; + + pdr = pc_drno_to_drive_struct( driveno); + + switch( opcode) { + case DEVCTL_GET_GEOMETRY: //formatまたはpartirionするときにRTFSが使うパラメータ + PRINTDEBUG( "DEVCTL_GET_GEOMETRY\n"); + if( (pdr->drive_flags & DRIVE_FLAGS_INSERTED) == 0) { /* 抜かれていた場合 */ + if( SDCARD_OutFlag == TRUE) { /* 今現在も抜かれているとき */ + return( -1); + }else{ /* 今現在は再挿入されているとき */ + /*-- GoIdleセット --*/ + if( func_SDCARD_Out != i_sdmcRemovedIntr) { + func_usr_sdmc_out = func_SDCARD_Out; //ユーザコールバック取得 + } + sdmcGoIdle( func_SDCARD_In, i_sdmcRemovedIntr); //カード初期化シーケンス + /*------------------*/ + } + } + + rtfs_memset( &gc, (byte)0, sizeof(gc)); + + sdi_get_CHS_params(); //最初に呼ぶこと + sdi_get_fatparams(); + sdi_get_nom(); + + PRINTDEBUG( "heads : 0x%x\n", sdmc_current_spec.heads); + PRINTDEBUG( "secptrack : 0x%x\n", sdmc_current_spec.secptrack); + PRINTDEBUG( "cylinders : 0x%x\n", sdmc_current_spec.cylinders); + PRINTDEBUG( "SC : 0x%x\n", sdmc_current_spec.SC); + PRINTDEBUG( "BU : 0x%x\n", sdmc_current_spec.BU); + PRINTDEBUG( "RDE : 0x%x\n", sdmc_current_spec.RDE); + PRINTDEBUG( "SS : 0x%x\n", sdmc_current_spec.SS); + PRINTDEBUG( "RSC : 0x%x\n", sdmc_current_spec.RSC); + PRINTDEBUG( "FATBITS : 0x%x\n", sdmc_current_spec.FATBITS); + PRINTDEBUG( "SF : 0x%x\n", sdmc_current_spec.SF); + PRINTDEBUG( "SSA : 0x%x\n", sdmc_current_spec.SSA); + PRINTDEBUG( "NOM : 0x%x\n", sdmc_current_spec.NOM); + + gc.dev_geometry_lbas = (sdmc_current_spec.adjusted_memory_capacity);// - sdmc_current_spec.NOM); + gc.dev_geometry_heads = sdmc_current_spec.heads; + gc.dev_geometry_cylinders = sdmc_current_spec.cylinders; + gc.dev_geometry_secptrack = sdmc_current_spec.secptrack; + /**/ + gc.fmt_parms_valid = TRUE; + gc.fmt.oemname[0] = 'C'; + gc.fmt.oemname[1] = 'T'; + gc.fmt.oemname[2] = 'R'; + gc.fmt.oemname[3] = '\0'; + gc.fmt.secpalloc = sdmc_current_spec.SC; /*sectors per cluster(FIX by capacity)*/ + gc.fmt.secreserved = sdmc_current_spec.RSC;//sdmc_current_spec.RSC;/*reserved sectors(FIX 1 at FAT12,16)*/ + gc.fmt.numfats = 2; + gc.fmt.secpfat = sdmc_current_spec.SF; + gc.fmt.numhide = sdmc_current_spec.NOM; /**/ + gc.fmt.numroot = sdmc_current_spec.RDE; /*FIX*/ + gc.fmt.mediadesc = 0xF8; + gc.fmt.secptrk = sdmc_current_spec.secptrack; //CHS Recommendation + gc.fmt.numhead = sdmc_current_spec.heads; + gc.fmt.numcyl = sdmc_current_spec.cylinders; + gc.fmt.physical_drive_no = driveno; + gc.fmt.binary_volume_label = BIN_VOL_LABEL; + gc.fmt.text_volume_label[0] = '\0'; + //TODO:dev_geometry_lbasもセットする必要あるか調べること + PRINTDEBUG( "heads : 0x%x, secptrack : 0x%x, cylinders : 0x%x\n", gc.dev_geometry_heads, gc.dev_geometry_secptrack, gc.dev_geometry_cylinders); + +#if (TARGET_OS_CTR == 1) + miCpuCopy8( &gc, pargs, sizeof(gc)); +// copybuff( pargs, &gc, sizeof(gc)); +#else + MI_CpuCopy8( &gc, pargs, sizeof(gc)); +#endif + return( 0); + + case DEVCTL_FORMAT: + PRINTDEBUG( "DEVCTL_FORMAT\n"); + sdi_build_partition_table(); //MBRセクタ(パーティションテーブル含む)書き込み + return( 0); + + case DEVCTL_REPORT_REMOVE: //抜かれたとき + PRINTDEBUG( "DEVCTL_REPORT_REMOVE\n"); + pdr->drive_flags &= ~DRIVE_FLAGS_INSERTED; + return( 0); + + case DEVCTL_CHECKSTATUS: //REMOVABLEの場合、毎回R/W前に呼ばれる + PRINTDEBUG( "DEVCTL_CHECKSTATUS\n"); + if (!(pdr->drive_flags & DRIVE_FLAGS_REMOVABLE)) { //リムーバブルでない場合 + return(DEVTEST_NOCHANGE); + } + if (pdr->drive_flags & DRIVE_FLAGS_INSERTED) { /* 抜かれてない場合 */ + if( rtfs_first_stat_flag[driveno]) { //初回のCHECKSTATUS時 + rtfs_first_stat_flag[driveno] = 0; + PRINTDEBUG( "CHANGED!\n"); + return(DEVTEST_CHANGED); + }else{ + PRINTDEBUG( "DEVTEST_NOCHANGE\n"); + return( DEVTEST_NOCHANGE); + } + }else{ /* 抜かれていた場合 */ + if( SDCARD_OutFlag == FALSE) { /* 排出フラグ参照 */ + pdr->drive_flags |= DRIVE_FLAGS_INSERTED; + /*-- GoIdleセット --*/ + if( func_SDCARD_Out != i_sdmcRemovedIntr) { + func_usr_sdmc_out = func_SDCARD_Out; //ユーザコールバック取得 + } + sdmcGoIdle( func_SDCARD_In, i_sdmcRemovedIntr); //カード初期化シーケンス + /*------------------*/ + PRINTDEBUG( "DEVTEST_CHANGED\n"); + return( DEVTEST_CHANGED); //挿さっている + }else{ + PRINTDEBUG( "DEVTEST_NOMEDIA\n"); + return( DEVTEST_NOMEDIA); //挿さってない + } + } + + case DEVCTL_WARMSTART: //attachのときしか呼ばれない + PRINTDEBUG( "DEVCTL_WARMSTART\n"); + /*-- GoIdleセット --*/ + if( func_SDCARD_Out != i_sdmcRemovedIntr) { + func_usr_sdmc_out = func_SDCARD_Out; //ユーザコールバック取得 + } + sdmcGoIdle( func_SDCARD_In, i_sdmcRemovedIntr); //カード初期化シーケンス + /*------------------*/ + pdr->drive_flags |= (DRIVE_FLAGS_VALID | DRIVE_FLAGS_REMOVABLE | DRIVE_FLAGS_PARTITIONED); + pdr->partition_number = 0; + + if( SDCARD_OutFlag == FALSE) { /* 排出フラグ参照 */ + pdr->drive_flags |= DRIVE_FLAGS_INSERTED; + }else{ /* カード未挿入のとき */ + pdr->drive_flags &= (~(DRIVE_FLAGS_INSERTED)); //抜かれているだけではVALIDフラグは落とさないらしい + } + return( 0); + + case DEVCTL_POWER_RESTORE: + PRINTDEBUG( "DEVCTL_POWER_RESTORE\n"); + break; + + case DEVCTL_POWER_LOSS: + PRINTDEBUG( "DEVCTL_POWER_LOSS\n"); + break; + + default: + PRINTDEBUG( "DEVCTL_unknown\n"); + break; + } + return( 0); +} + +/*---------------------------------------------------------------------------* + 抜取コールバック関数 + + RTFSが次回"DEVCTL_GET_GEOMETRY"を行うとき、ここでセットしたパラメータを知る + *---------------------------------------------------------------------------*/ +void i_sdmcRemovedIntr( void) +{ + DDRIVE *pdr; + + pdr = pc_drno_to_drive_struct( sdmc_drive_no); + if( pdr) { + pdr->dev_table_perform_device_ioctl( pdr->driveno, + DEVCTL_REPORT_REMOVE, + (void*)0); + } + + if( func_usr_sdmc_out) { + func_usr_sdmc_out(); //ユーザコールバック + } +} + + +/*---------------------------------------------------------------------------* + Name: sdmcRtfsAttach + + Description: sdmcドライバをドライブに割り当てる + + Arguments: driveno : ドライブ番号 + + Returns: + *---------------------------------------------------------------------------*/ +BOOL sdmcRtfsAttach( int driveno) +{ + BOOLEAN result; + DDRIVE pdr; + + pdr.dev_table_drive_io = sdmcRtfsIo; + pdr.dev_table_perform_device_ioctl = sdmcRtfsCtrl; + pdr.register_file_address = (dword) 0; /* Not used */ + pdr.interrupt_number = 0; /* Not used */ + pdr.drive_flags = 0;//DRIVE_FLAGS_FAILSAFE; + pdr.partition_number = 0; /* Not used */ + pdr.pcmcia_slot_number = 0; /* Not used */ + pdr.controller_number = 0; + pdr.logical_unit_number = 0; + + result = rtfs_attach( driveno, &pdr, "SD"); //構造体がFSライブラリ側にコピーされる + + /*drivenoをグローバル変数に記憶*/ + sdmc_drive_no = driveno; + + return( result); +} + + + +/*SD File System Specification(仕様書)に基づいた値を出す*/ +static void sdi_get_CHS_params( void) +{ + int mbytes; + +// mbytes = (sdmc_current_spec.card_capacity / (1024 * 1024)) * 512; + mbytes = (sdmc_current_spec.card_capacity >> 11); + + while( 1) { + if( mbytes <= 2) { + sdmc_current_spec.heads = 2; + sdmc_current_spec.secptrack = 16; + break; + } + if( mbytes <= 16) { + sdmc_current_spec.heads = 2; + sdmc_current_spec.secptrack = 32; + break; + } + if( mbytes <= 32) { + sdmc_current_spec.heads = 4; + sdmc_current_spec.secptrack = 32; + break; + } + if( mbytes <= 128) { + sdmc_current_spec.heads = 8; + sdmc_current_spec.secptrack = 32; + break; + } + if( mbytes <= 256) { + sdmc_current_spec.heads = 16; + sdmc_current_spec.secptrack = 32; + break; + } + if( mbytes <= 504) { + sdmc_current_spec.heads = 16; + sdmc_current_spec.secptrack = 63; + break; + } + if( mbytes <= 1008) { + sdmc_current_spec.heads = 32; + sdmc_current_spec.secptrack = 63; + break; + } + if( mbytes <= 2016) { + sdmc_current_spec.heads = 64; + sdmc_current_spec.secptrack = 63; + break; + } + if( mbytes <= 2048) { + sdmc_current_spec.heads = 128; + sdmc_current_spec.secptrack = 63; + break; + } + if( mbytes <= 4032) { + sdmc_current_spec.heads = 128; + sdmc_current_spec.secptrack = 63; + break; + } + if( mbytes <= 32768) { + sdmc_current_spec.heads = 255; + sdmc_current_spec.secptrack = 63; + break; + } + } + + /*シリンダ数を計算*/ + sdmc_current_spec.cylinders = (sdmc_current_spec.memory_capacity / + (sdmc_current_spec.heads * sdmc_current_spec.secptrack)); + + /*memory_capacityを再計算してadjusted_memory_capacityに格納*/ + sdmc_current_spec.adjusted_memory_capacity = sdmc_current_spec.cylinders * + (sdmc_current_spec.heads * sdmc_current_spec.secptrack); +} + + +/*引数を超える最も小さい整数を算出する*/ +static u32 sdi_get_ceil( u32 cval, u32 mval) +{ + return( (cval / mval) + (1 * (cval % mval != 0))); +} + + +/*マスターブートセクタのセクタ数を返す*/ +static void sdi_get_nom( void) +{ + u32 RSC = 1; //FAT12,16では1 + u32 RDE = 512; //ルートディレクトリエントリ。FIX + u32 SS = 512; //セクタサイズ。FIX + u32 TS, SC, n; + u32 MAX, SFdash; + + TS = sdmc_current_spec.adjusted_memory_capacity; + SC = sdmc_current_spec.SC; + + sdmc_current_spec.SF = sdi_get_ceil( TS/SC * sdmc_current_spec.FATBITS, SS*8); + + /*-----------------------SDHCのとき----------------------------*/ + if( sdmc_current_spec.csd_ver2_flag) { + sdmc_current_spec.NOM = sdmc_current_spec.BU; + do { + n = sdi_get_ceil( 2*sdmc_current_spec.SF, sdmc_current_spec.BU); + sdmc_current_spec.RSC = (sdmc_current_spec.BU * n) - ( 2 * sdmc_current_spec.SF); + if( sdmc_current_spec.RSC < 9) { + sdmc_current_spec.RSC += sdmc_current_spec.BU; + } + sdmc_current_spec.SSA = sdmc_current_spec.RSC + (2 * sdmc_current_spec.SF); + do { + MAX = ((TS - sdmc_current_spec.NOM - sdmc_current_spec.SSA) / SC) + 1; + SFdash = sdi_get_ceil( (2+(MAX-1)) * sdmc_current_spec.FATBITS, SS*8); + if( SFdash > sdmc_current_spec.SF) { + sdmc_current_spec.SSA += sdmc_current_spec.BU; + sdmc_current_spec.RSC += sdmc_current_spec.BU; + }else{ + break; + } + }while( 1); + if( SFdash != sdmc_current_spec.SF) { + sdmc_current_spec.SF -= 1; + }else{ + break; + } + }while( 1); + }else{ /*-------------------------SDのとき-------------------------------*/ + do { + sdmc_current_spec.SSA = RSC + ( 2 * sdmc_current_spec.SF) + sdi_get_ceil( 32*RDE, SS); + n = sdi_get_ceil( sdmc_current_spec.SSA, sdmc_current_spec.BU); + sdmc_current_spec.NOM = (sdmc_current_spec.BU * n) - sdmc_current_spec.SSA; + if( sdmc_current_spec.NOM != sdmc_current_spec.BU) { + sdmc_current_spec.NOM += sdmc_current_spec.BU; + } + do { + MAX = ((TS - sdmc_current_spec.NOM - sdmc_current_spec.SSA) / SC) + 1; + SFdash = sdi_get_ceil( (2+(MAX-1)) * sdmc_current_spec.FATBITS, SS*8); + if( SFdash > sdmc_current_spec.SF) { + sdmc_current_spec.NOM += sdmc_current_spec.BU; + }else{ + break; + } + }while( 1); + if( SFdash != sdmc_current_spec.SF) { + sdmc_current_spec.SF = SFdash; + }else{ + break; //complete + } + }while( 1); + } + + return; +} + +/*FATのビット数を返す*/ +static void sdi_get_fatparams( void) +{ + int mbytes; + +// mbytes = (sdmc_current_spec.card_capacity / (1024 * 1024)) * 512; + mbytes = (sdmc_current_spec.card_capacity >> 11); + + if( mbytes <= 64) { + sdmc_current_spec.FATBITS = 12; + sdmc_current_spec.RDE = 512; + sdmc_current_spec.RSC = 1; + }else{ + if( mbytes <= 2048) { + sdmc_current_spec.FATBITS = 16; + sdmc_current_spec.RDE = 512; + sdmc_current_spec.RSC = 1; + }else{ + sdmc_current_spec.FATBITS = 32; + sdmc_current_spec.RDE = 0; //FAT32のときは未使用。0にしておかないとRTFSが BAD FORMAT を返す。 + sdmc_current_spec.RSC = 1; + } + } + + if( mbytes <= 8) { + sdmc_current_spec.SC = 16; + sdmc_current_spec.BU = 16; + return; + } + if( mbytes <= 64) { + sdmc_current_spec.SC = 32; + sdmc_current_spec.BU = 32; + return; + } + if( mbytes <= 256) { + sdmc_current_spec.SC = 32; + sdmc_current_spec.BU = 64; + return; + } + if( mbytes <= 1024) { + sdmc_current_spec.SC = 32; + sdmc_current_spec.BU = 128; + return; + } + if( mbytes <= 2048) { + sdmc_current_spec.SC = 64; + sdmc_current_spec.BU = 128; + return; + } + if( mbytes <= 32768) { + sdmc_current_spec.SC = 64; + sdmc_current_spec.BU = 8192; + return; + } +} + +/*MBRセクタ(パーティションセクタ含む)を生成して書き込む*/ +static void sdi_build_partition_table( void) +{ + u16 MbrSectDat[512/2]; + u32 starting_head, starting_sect, starting_cyl; + u32 ending_head, ending_sect, ending_cyl; + u32 total_sect; +#if (SD_DEBUG_PRINT_ON == 1) + u32 starting_data, ending_data; +#endif + u32 systemid; + SdmcResultInfo SdResult; + + /**/ + starting_head = sdmc_current_spec.NOM % (sdmc_current_spec.heads * + sdmc_current_spec.secptrack); + starting_head /= sdmc_current_spec.secptrack; + + /**/ + starting_sect = (sdmc_current_spec.NOM % sdmc_current_spec.secptrack) + 1; + + /**/ + starting_cyl = sdmc_current_spec.NOM / (sdmc_current_spec.heads * + sdmc_current_spec.secptrack); + + /**/ + total_sect = (sdmc_current_spec.adjusted_memory_capacity - sdmc_current_spec.NOM); + ending_head = (sdmc_current_spec.NOM + total_sect - 1) % + (sdmc_current_spec.heads * sdmc_current_spec.secptrack); + ending_head /= sdmc_current_spec.secptrack; + + /**/ + ending_sect = ((sdmc_current_spec.NOM + total_sect - 1) % + sdmc_current_spec.secptrack) + 1; + + /**/ + ending_cyl = (sdmc_current_spec.NOM + total_sect - 1) / + (sdmc_current_spec.heads * sdmc_current_spec.secptrack); + + /**/ + if( sdmc_current_spec.FATBITS == 32) { //FAT32のとき + if( total_sect < 0xFB0400) { //8032.5MBが閾値(SD FileSystemSpec2.00参照) + systemid = 0x0B; /* FAT32 */ + }else{ + systemid = 0x0C; /* FAT32(拡張INT13対応) */ + } + }else{ //FAT12,FAT16のとき + if( total_sect < 32680) { + systemid = 0x01; /* FAT12 */ + }else if( total_sect < 65536) { + systemid = 0x04; /* FAT16(16MB〜32MB未満) */ + }else{ + systemid = 0x06; /* FAT16(32MB〜4GB) */ + } + } + + /*MBRセクタ(パーティションテーブル含む)作成*/ +#if (TARGET_OS_CTR == 1) + miCpuFill8( MbrSectDat, 0, 512); +#else + MI_CpuFill8( MbrSectDat, 0, 512); +#endif + MbrSectDat[446/2] = (starting_head<<8); + //上位8bit:starting_cylの下位8bit, 下位8bit:starting_cylの上位2bit + starting_sect 6bit. + MbrSectDat[448/2] = (starting_cyl<<8) + ((starting_cyl>>2) & 0xC0) + starting_sect; + MbrSectDat[450/2] = (ending_head<<8) + systemid; + //上位8bit:ending_cylの下位8bit, 下位8bit:ending_cylの上位2bit + ending_sect 6bit. + MbrSectDat[452/2] = (ending_cyl<<8) + ((ending_cyl>>2) & 0xC0) + ending_sect; + MbrSectDat[454/2] = sdmc_current_spec.NOM; + MbrSectDat[456/2] = (sdmc_current_spec.NOM>>16); + MbrSectDat[458/2] = total_sect; + MbrSectDat[460/2] = (total_sect>>16); + MbrSectDat[510/2] = 0xAA55; + /*セクタ0に書き込み*/ + sdmcWriteFifo( MbrSectDat, 1, 0, NULL, &SdResult); + + /**/ + PRINTDEBUG( "total sect : 0x%x\n", total_sect); + PRINTDEBUG( "starting head : 0x%x\n", starting_head); + PRINTDEBUG( "starting sect : 0x%x\n", starting_sect); + PRINTDEBUG( "starting cyl : 0x%x\n", starting_cyl); + PRINTDEBUG( "ending head : 0x%x\n", ending_head); + PRINTDEBUG( "ending sect : 0x%x\n", ending_sect); + PRINTDEBUG( "ending cyl : 0x%x\n", ending_cyl); + PRINTDEBUG( "\n"); +#if (SD_DEBUG_PRINT_ON == 1) + starting_data = (starting_cyl<<8) + ((starting_cyl>>2) & 0xC0) + starting_sect; + PRINTDEBUG( "starting data : 0x%x\n", starting_data); + ending_data = (ending_cyl<<8) + ((ending_cyl>>2) & 0xC0) + ending_sect; + PRINTDEBUG( "endign data : 0x%x\n", ending_data); +#endif +} + +//#endif /*(INCLUDE_SD)*/ diff --git a/build/libraries/devices/rom_sdmc/ARM7/sdif.c b/build/libraries/devices/rom_sdmc/ARM7/sdif.c new file mode 100644 index 0000000..5ee0104 --- /dev/null +++ b/build/libraries/devices/rom_sdmc/ARM7/sdif.c @@ -0,0 +1,1188 @@ +/* + Project: CTR SD Card driver + File: sd_card.c + + 2006, Research and Development Department, Nintendo. +*/ + +#include +#include "sdmc_config.h" +#include "sdif_reg.h" /* IP 対応レジスタ定義 */ +#include "sdmc.h" +#include "sdif_ip.h" /* IP 対応フラグ定義 */ + +#if (SD_DEBUG_PRINT_ON == 1) + #if (CTR_DEF_ENVIRONMENT_DSEMU == 1) + #define PRINTDEBUG osTPrintf + #else + #include + #define PRINTDEBUG vlink_dos_printf + #endif +#else + #define PRINTDEBUG( ...) ((void)0) +#endif + + +#define ADD_CHECK 1 + +/*********************************************************************** + グローバル +***********************************************************************/ +u16 SD_CID[8]; /* CID保存用 (Card IDentification register) : ID*/ +u16 SD_CSD[8]; /* CSD保存用 (Card Specific Data register) : spec*/ +u16 SD_OCR[2]; /* OCR保存用 (Operation Condition Register) : voltage and status*/ +u16 SD_SCR[4]; /* SCR保存用 (Sd card Configulation Register) : bus-width, card-ver, etc*/ +u16 SD_RCA; /* RCA保存用 (Relative Card Address register) : address*/ + +s16 SDCARD_MMCFlag; /* MMCカードフラグ */ +s16 SDCARD_SDHCFlag; /* SDHCカードフラグ(ここではPhysicalLayer2.0の意) */ +u16 SD_port_number; /* 現在のポート番号 */ + +/*********************************************************************** + 外部参照変数 +***********************************************************************/ +extern volatile u16 SDCARD_ErrStatus; /* エラーステータス */ +extern volatile u32 SDCARD_Status; /* カードステータス */ +//extern volatile s16 SDCARD_OutFlag; /* カード排出発生判定フラグ */ +//extern void (*func_SDCARD_Out)(void); /* カード排出イベント用コールバック保存用 */ + + + + + +void SD_DisableInfo( void); + + + +/*---------------------------------------------------------------------------* + Name: SD_Init + + Description: reset and initialize SD card interface + SDカードIPのリセットと初期設定 + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void SD_Init(void) +{ + SD_AndFPGA( SOFT_RST,(~(SOFT_RST_SDIF_RST))); /* SD I/F モジュールをリセット */ + SD_OrFPGA( SOFT_RST,((SOFT_RST_SDIF_RST))); /* SD I/F モジュールをリセット復帰 */ + + SD_AndFPGA( SD_STOP,(~SD_STOP_STP)); /* データ転送終了クリア */ +} + +/*---------------------------------------------------------------------------* + Name: SD_EnableInfo + + Description: enable SD card insert and remove interrupts. + SDカードの挿入/抜取 割り込みを許可する + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void SD_EnableInfo( void) +{ + if(SD_port_number == SDCARD_PORT0) + { + SD_AndFPGA(SD_INFO1,(~(SD_INFO1_INSERT | SD_INFO1_REMOVE))); /* SD_INFO1レジスタの card inserted removedをクリア */ + SD_AndFPGA(SD_INFO1_MASK,(~(SD_INFO1_MASK_INSERT | SD_INFO1_MASK_REMOVE))); /* 挿/抜 割り込み許可 */ + } + else if(SD_port_number == SDCARD_PORT1) + { /* ポート1はCD端子が繋がっていないので実質無効 */ + SD_AndFPGA(EXT_CD,(~(EXT_CD_PORT1_INSERT | EXT_CD_PORT1_REMOVE))); /* EXT_CD レジスタの card inserted removedをクリア */ + SD_AndFPGA(EXT_CD_MASK,(~(EXT_CD_MASK_PORT1INSERT | EXT_CD_MASK_PORT1REMOVE))); /* 挿抜 割り込み許可 */ + } +} +/*---------------------------------------------------------------------------* + Name: SD_DisableInfo + + Description: disable SD card insert and remove interrupts. + SDカードの挿入/抜取 割り込みを禁止する + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void SD_DisableInfo( void) +{ + if(SD_port_number == SDCARD_PORT0) + { + SD_AndFPGA(SD_INFO1,(~(SD_INFO1_INSERT | SD_INFO1_REMOVE))); /* SD_INFO1レジスタの card inserted removedをクリア */ + SD_OrFPGA(SD_INFO1_MASK,(SD_INFO1_MASK_INSERT | SD_INFO1_MASK_REMOVE)); /* 挿/抜 割り込み禁止 */ + } + else if(SD_port_number == SDCARD_PORT1) + { /* ポート1はCD端子が繋がっていないので実質無効 */ + SD_AndFPGA(EXT_CD,(~(EXT_CD_PORT1_INSERT | EXT_CD_PORT1_REMOVE))); /* EXT_CD レジスタの card inserted removedをクリア */ + SD_OrFPGA(EXT_CD_MASK,(EXT_CD_MASK_PORT1INSERT | EXT_CD_MASK_PORT1REMOVE)); /* 挿抜 割り込み禁止 */ + } +} + +/*---------------------------------------------------------------------------* + Name: SD_Command + + Description: send command that the card will response only. + コマンドを送出する(レスポンスが返ってくるだけのコマンド用) + + Arguments: ucCommand : command number + + Returns: 0 : success + >0 : error + *---------------------------------------------------------------------------*/ +u16 SD_Command(u16 ucCommand) +{ + SD_AndFPGA(SD_INFO2,(~SD_INFO2_ERR_ALLCLR)); /* SD Card I/F の 全エラーをクリア */ + SD_AndFPGA(SD_INFO1,(~SD_INFO1_RES_END)); /* SD_INFO1レジスタの Response end クリア */ + SD_AndFPGA(SD_INFO2_MASK,(~SD_INFO2_MASK_ALLERRMASK)); /* SD Card I/F の 全エラー割込み許可 */ + + SD_SetFPGA(SD_CMD,(ucCommand)); /* コマンド発行 */ + + while(!SD_CheckFPGAReg(SD_INFO1,SD_INFO1_RES_END)){ /* Response end 待ち */ + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトチェック */ + break; + } + } + + SD_OrFPGA(SD_INFO2_MASK,(SD_INFO2_MASK_ALLERRMASK)); /* SD Card I/F の全エラー割込み禁止 */ + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: SD_AppCommand + + Description: send apprication command. + アプリケーションコマンド(CMD55)を送出する + + Arguments: None + + Returns: 0 : success + >0 : error + *---------------------------------------------------------------------------*/ +u16 SD_AppCommand(void) +{ + PRINTDEBUG( " CMD55 (APP_CMD)\n"); + + /* argumentをセット */ + SD_SetFPGA(SD_ARG0,(0x0000)); /* Argument(15:0) = stuff bits */ + SD_SetFPGA(SD_ARG1,(SD_RCA)); /* Argument(31:16) = RCA */ + + SD_Command(SD_CMD_CMD | APP_CMD); /* CMD55発行、レスポンス(R1)待ち */ + +#if ADD_CHECK + /*SD_CheckStatusを行うと、直前にCMD8を発行していた場合、SDHC以外はCardStatusの + IllegalCommandエラーフラグが立ってしまうので、ここで引っかかることになる + (このフラグがクリアされるのは1コマンドぶん遅れるため) + SD Physical Layer 仕様書の Card Status参照*/ +// SD_CheckStatus(FALSE); /* コマンドレスポンス(R1) の Card Status チェック */ +#endif + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: SD_AppOpCond + + Description: get operating condition register data of SD card. + SDカードのACMD41を発行してOCRを取得する + + Arguments: None + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +u16 SD_AppOpCond(void) +{ + SD_ClrErr((u16)(~SDMC_ERR_FPGA_TIMEOUT)); /* タイムアウト以外のエラーをクリア */ + + while(!SDCARD_ErrStatus){ /* エラーが発生しない間は繰り返し */ + /* Argument(31:0) = OCR without busy (0x00100000 = 3.2-3.3V) */ + /*ホスト側で電圧を選択できる場合などは、初回にSD_ARG1を0にすることにより + カードが対応している電圧を問い合わせることができる。CTRは電圧3.3V決め打ち + なので問い合わせせず、いきなり3.3V対応をカードに要求する。対応できない + カードは Inactive Mode に移行する。*/ + SD_SetFPGA(SD_ARG0,(0x0000)); + if( SDCARD_SDHCFlag) { + SD_SetFPGA(SD_ARG1,(0x4010)); + }else{ + SD_SetFPGA(SD_ARG1,(0x0010)); + } + + PRINTDEBUG( " ACMD41 (SD_SEND_OP_COND)\n"); + SD_Command(SD_CMD_ACMD | SD_APP_OP_COND); /* ACMD41発行、レスポンス(R3)待ち */ + + if(!SDCARD_ErrStatus){ /* エラーステータスの確認(エラー無し?)*/ + SD_GetFPGA(SD_OCR[0],SD_RSP0); /* レスポンス(R3)からOCR取得 */ + SD_GetFPGA(SD_OCR[1],SD_RSP1); /* レスポンス(R3)からOCR取得 */ + if(SD_RSP1 & RSP_R3_OCR31){ /* OCR(レジスタ)の31bit目チェック(busy?) */ + break; + } + } + SD_AppCommand(); /* 決定済みのRCAを設定しCMD55発行 */ + } + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: SD_SendOpCond + + Description: send CMD1 without busy for MMC + MMC の CMD1を発行する(SDのACMD41に位置するコマンド) + + Arguments: None + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +u16 SD_SendOpCond(void) +{ + PRINTDEBUG( " CMD1 (SEND_OP_COND)\n"); + + SD_ClrErr((u16)(~SDMC_ERR_FPGA_TIMEOUT)); /* タイムアウトエラーをクリア */ + + while(!SDCARD_ErrStatus){ /* エラーが発生しない間は繰り返し */ + SD_SetFPGA(SD_ARG0,(0x0000)); /* Argument(15:0) for MMC (None for SD) */ + SD_SetFPGA(SD_ARG1,(0x0010)); /* Argument(31:16) for MMC (None for SD) */ + SD_Command(SD_CMD_CMD | SEND_OP_COND); /* CMD1発行、レスポンス(R1)待ち */ + if(!SDCARD_ErrStatus){ /* エラーステータスの確認(エラー無し?) */ + SD_GetFPGA(SD_OCR[0],SD_RSP0); + SD_GetFPGA(SD_OCR[1],SD_RSP1); + if(SD_RSP1 & RSP_R3_OCR31){ /* OCR(レジスタ)の31bit目チェック(busy?) */ + break; + } + } + } + return SDCARD_ErrStatus; +} + + +/*---------------------------------------------------------------------------* + Name: SD_SendIfCond + + Description: send CMD8 + CMD8を発行する(Physical Layer 2.00で追加されたコマンド) + + Arguments: None + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +u16 SD_SendIfCond(void) +{ + PRINTDEBUG( " CMD8 (SEND_IF_COND)\n"); + + SD_ClrErr((u16)(~SDMC_ERR_FPGA_TIMEOUT)); /* タイムアウトエラーをクリア */ + + /* (31:12) Reserved bits, (11:8) supply voltage(VHS), (7:0) check pattern */ + SD_SetFPGA(SD_ARG0,(0x01AA)); /* Argument */ + SD_SetFPGA(SD_ARG1,(0x0000)); /* Argument */ + + SD_Command(SD_CMD_CMD | SEND_IF_COND_EXT); /* CMD8発行、レスポンス(R7)待ち */ + + if(!SDCARD_ErrStatus){ /* エラーステータスの確認(エラー無し?) */ + SDCARD_SDHCFlag = TRUE; /* SDHC */ +// SD_GetFPGA(SD_R7[0],SD_RSP0); +// SD_GetFPGA(SD_R7[1],SD_RSP1); + }else{ + SDCARD_SDHCFlag = FALSE; + } + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: SD_SendRelativeAddr + + Description: send relative addr + CMD3を発行し、SDカードの場合はレスポンスのRCAを取得する + (RCAは他のコマンド発行時にArgumentとして必要) + + Arguments: None + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +u16 SD_SendRelativeAddr(void) +{ + PRINTDEBUG( " CMD3 (SEND_RELATIVE_ADDR)\n"); + + if(SDCARD_MMCFlag){ /* MMCカードフラグ ON ? */ + SD_SetFPGA(SD_ARG0,(0x0000)); /* Argument(15:0) */ + SD_SetFPGA(SD_ARG1,(0x0001)); /* Argument(31:16) = 0x0001 (松下drvはなぜか0x0100にしていた) */ + } /* SDカードのときはArgument(31:0) = stuff bits */ + + SD_Command(SD_CMD_CMD | SEND_RELATIVE_ADDR); /* CMD3発行、レスポンス(R6)待ち */ + + if(!SDCARD_ErrStatus){ /* エラーステータスの確認(エラー無し?) */ + if(SDCARD_MMCFlag){ /* MMCカードフラグ ON ? */ + SD_RCA = 0x0001; /* RCA <- 1 (松下drvはなぜか0x0100にしていた) */ + }else{ + SD_GetFPGA(SD_RCA,SD_RSP1); /* レスポンスレジスタからRCAを取得 */ + } + } + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: SD_SelectCard + + Description: toggle card between the stand-by and transfer states. + CMD7を発行してスタンバイモードと転送モードを切り替える + + Arguments: None + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +u16 SD_SelectCard(void) +{ + PRINTDEBUG( " CMD7 (SELECT#/DESELECT_CARD)\n"); + + SD_SetFPGA(SD_ARG0,(0x0000)); /* Argument(15:0) = stuff bits*/ + SD_SetFPGA(SD_ARG1,(SD_RCA)); /* Argument(31:16) = RCA */ + + SD_Command(SD_CMD_CMD | SELECT_CARD); /* CMD7発行、レスポンス(R1b)待ち */ + +#if ADD_CHECK + SD_CheckStatus(FALSE); /* コマンドレスポンス(R1) の Card Status チェック */ +#endif + + return SDCARD_ErrStatus; + +} + +/*---------------------------------------------------------------------------* + Name: SD_SetBlockLength + + Description: set of block length. + SDカードのブロックレングスを設定する。 + 注意:multiple read のときに SD_SIZEレジスタに512以外の値を + 設定すると正しく動作しない(IP reg spec資料より)。 + + Arguments: ulBlockLength : bytes of a block ( must be multiplier of 2) + (memo : the default block length is as specified in the CSD.) + 1ブロックの長さ:2の乗数を指定すること + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +u16 SD_SetBlockLength(u32 ulBlockLength) +{ + u16 usValue; + + PRINTDEBUG( " CMD16 (SET_BLOCKLEN)\n"); + + /*------- IPの transfer length を設定 -------*/ + if(ulBlockLength == 512){ + SD_SetFPGA(SD_SIZE,(SD_SIZE_DATA_LENGTH_512B)); /* SDカードデータ転送サイズ 512Bytes 設定 */ + }else{ + usValue = (u16)ulBlockLength; /* 16bitに変換 */ + SD_SetFPGA(SD_SIZE,(usValue)); /* IPにSDカードデータ転送サイズを設定 */ + }/*------------------------------------------*/ + + /*------- カードの設定 -------*/ + /* argument(31:0) = block length */ + SD_SetFPGA(SD_ARG0,(((LELONG *)&ulBlockLength)->dt2word.low)); + SD_SetFPGA(SD_ARG1,(((LELONG *)&ulBlockLength)->dt2word.high)); + + SD_Command(SD_CMD_CMD | SET_BLOCKLEN); /* CMD16発行、レスポンス(R1)待ち */ +#if ADD_CHECK + SD_CheckStatus(FALSE); /* コマンドレスポンス(R1) の Card Status チェック */ +#endif + /*----------------------------*/ + return SDCARD_ErrStatus; +} + + +/*---------------------------------------------------------------------------* + Name: SD_SendCID + + Description: get card identification data (128bits). + SDカードのCID値を取得する + + Arguments: None + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +u16 SD_SendCID(void) +{ + PRINTDEBUG( " CMD2 (ALL_SEND_CID)\n"); + /* Argument(31:0) = stuff bits */ + SD_Command(SD_CMD_CMD | ALL_SEND_CID); /* CMD2発行、レスポンス(R2)待ち */ + + if(!SDCARD_ErrStatus){ /* エラーステータスの確認(エラー無し?) */ + SD_GetFPGA(SD_CID[0],SD_RSP0); + SD_GetFPGA(SD_CID[1],SD_RSP1); + SD_GetFPGA(SD_CID[2],SD_RSP2); + SD_GetFPGA(SD_CID[3],SD_RSP3); + SD_GetFPGA(SD_CID[4],SD_RSP4); + SD_GetFPGA(SD_CID[5],SD_RSP5); + SD_GetFPGA(SD_CID[6],SD_RSP6); + SD_GetFPGA(SD_CID[7],SD_RSP7); + } + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: SD_SendCSD + + Description: get card specific data + SDカードのCSD値を取得する + + Arguments: None + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +u16 SD_SendCSD(void) +{ + PRINTDEBUG( " CMD9 (SEND_CSD)\n"); + + SD_SetFPGA(SD_ARG0,(0x0000)); /* Argument(15:0) = stuff bits */ + SD_SetFPGA(SD_ARG1,(SD_RCA)); /* Argument(31:16) = RCA */ + + SD_Command(SD_CMD_CMD | SEND_CSD); /* CMD9発行、レスポンス(R2)待ち */ + + if(!SDCARD_ErrStatus){ /* エラーステータスの確認(エラー無し?) */ + SD_GetFPGA(SD_CSD[0],SD_RSP0); + SD_GetFPGA(SD_CSD[1],SD_RSP1); + SD_GetFPGA(SD_CSD[2],SD_RSP2); + SD_GetFPGA(SD_CSD[3],SD_RSP3); + SD_GetFPGA(SD_CSD[4],SD_RSP4); + SD_GetFPGA(SD_CSD[5],SD_RSP5); + SD_GetFPGA(SD_CSD[6],SD_RSP6); + SD_GetFPGA(SD_CSD[7],SD_RSP7); + } + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: SD_SendStatus + + Description: send status read command (compatible to the MMC protocol). + マルチメディアカード互換方式でのstatus取得コマンド発行 + + Arguments: None + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +u16 SD_SendStatus(void) +{ + PRINTDEBUG( " CMD13 (Send STATUS)\n"); + + SD_SetFPGA(SD_ARG0,(0x0000)); /* Argument(15:0) = stuff bits */ + SD_SetFPGA(SD_ARG1,(SD_RCA)); /* Argument(31:16) = RCA */ + + /* カード排出の重複を防ぐため */ + SD_AndFPGA(SD_INFO2,(~SD_INFO2_ERR_ALLCLR)); /* SD Card I/F の 全てのエラーをクリア */ + SD_AndFPGA(SD_INFO1,(~SD_INFO1_RES_END)); /* SD_INFO1レジスタの Response end クリア */ + SD_AndFPGA(SD_INFO2_MASK,(~SD_INFO2_MASK_ALLERRMASK)); /* SD Card I/F の 全エラー割込み許可 */ + + SD_SetFPGA(SD_CMD,(SD_CMD_CMD | SD_SEND_STATUS)); /* CMD13発行 */ + + while(!SD_CheckFPGAReg(SD_INFO1,SD_INFO1_RES_END)){ /* Response end (R1)待ち */ + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ + break; + } + } + + SD_OrFPGA(SD_INFO2_MASK,(SD_INFO2_MASK_ALLERRMASK)); /* SD Card I/F の 全エラー割込み禁止 */ + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: SD_SendSCR + + Description: get condition data. + SDカード内のSCRレジスタ値取得コマンド発行。この後カードは + DATライン経由で1ブロック(8Bytesに設定しておくこと)送信してくる。 + MultiBlock R/W と異なり、DATライン経由で転送されてくるSDカードの + レジスタは、MSBから先に送られてくることに注意。 + (Physical Layer Specification 2.00 p12-13参照) + + Arguments: None + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +u16 SD_SendSCR(void) +{ + PRINTDEBUG( " ACMD51 (Send SCR)\n"); + /* Argument(31:0) = stuff bits */ +#if ADD_CHECK + SD_TransReadyFPGA(); /* 関連レジスタ初期化 */ + SD_AndFPGA(SD_INFO2_MASK,(~SD_INFO2_MASK_BRE)); /* SDカードからのデータ読出し要求割込み許可*/ + + SD_TransCommand((SD_CMD_ACMD | SEND_SCR)); /* SCR取得コマンド発行、レスポンス(R1)待ち */ +#endif + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: SD_SDStatus + + Description: send status read command (for SD card only). + SDカード専用方式でのstatus取得コマンド発行。この後カードは + DATライン経由で1ブロック(64Bytesに設定しておくこと)送信してくる。 + MultiBlock R/W と異なり、DATライン経由で転送されてくるSDカードの + レジスタは、MSBから先に送られてくることに注意。 + (Physical Layer Specification 2.00 p12-13参照) + + Arguments: None + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +u16 SD_SDStatus(void) +{ + PRINTDEBUG( " ACMD13 (SD_SD STATUS)\n"); + /* Argument(31:0) = stuff bits */ + SD_TransReadyFPGA(); /* 関連レジスタ初期化 */ + SD_AndFPGA(SD_INFO2_MASK,(~SD_INFO2_MASK_BRE)); /* SDカードからのデータ読出し要求割込み許可*/ + + SD_TransCommand((SD_CMD_ACMD | SD_STATUS)); /* ACMD13 Send the SD_CARD status コマンド発行、レスポンス(R1)待ち */ + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: SD_MultiReadBlock + + Description: send multiple block read command. + マルチブロックリードコマンド発行。この後カードは + DATライン経由でデータを送信してくる。 + + Arguments: ulOffset : offset address to read(BYTE). + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +u16 SD_MultiReadBlock(u32 ulOffset) +{ + PRINTDEBUG( " CMD18 (READ_MULTIPLE_BLOCK)\n"); + + SD_TransReadyFPGA(); /* INFOレジスタ初期化 */ + if( !SDCARD_UseFifoFlag) { /* FIFOを使わないとき */ + SD_AndFPGA(SD_INFO2_MASK,(~SD_INFO2_MASK_BRE)); /* SDカードからのデータ読出し要求割込み許可*/ + } + + /* 読み込み開始アドレス(オフセット)設定 */ + SD_SetFPGA(SD_ARG0,(((LELONG *)&ulOffset)->dt2word.low)); + SD_SetFPGA(SD_ARG1,(((LELONG *)&ulOffset)->dt2word.high)); + + SD_TransCommand((READ_MULTIPLE_BLOCK)); /* CMD18(マルチセクタリードコマンド)発行、レスポンス(R1)待ち */ + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: SD_ClockDivSet + + Description: set clock speed into the SD card. + (notice : clock into IP is 33.51MHz.) + (memo : default clock is 262KHz.) + SDカードへのクロック速度を設定する。CTRからIMCLK端子でIPに供給 + される基本クロックは33.51MHz。 + 起動直後のデフォルトでは128分周(262KHz)が設定されている。 + + Arguments: CSD responce include "TRAN_SPEED". + 予めCSDをSDカードから読み出しておいた、TRAN_SPEEDが入っている + 部分のCSD(CSD[5])。SDカード側で対応可能な周波数を参照するため。 + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +u16 SD_ClockDivSet(u16 usTranSpeed) +{ + u16 usTranTime; + + //CTRでは、IMCLKに入力されるクロックは 33.51Mhz + //SD_CLK_CTRL の default値は 0x0020( 128分周 = 262kHz) + /*------*/ + usTranTime = (u16)((usTranSpeed >> 11) & 0x000F); /* CSD[103:96] の time value(=4bit) 取得 */ + + usTranSpeed &= CSD_TRANSFER_RATE; /* CSD[103:96] の transfer rate unit を取得 */ + usTranSpeed = (u16)(usTranSpeed >> 8); /* transfer rate unit を下位8ビットに設定する */ + /*------*/ + + + switch( usTranSpeed) { + /*--- 100kbit/s(one dat line) = 100KHz, の倍数のとき ---*/ + case CSD_TRAN_SPEED_100K: + if(usTranTime > 0x000C){ /* time value が 5.5 より大きい? */ + SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_64)); /* 523KHz */ + } + else{ + if(usTranTime > 0x0006){ /* time value が 2.5 より大きい? */ + SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_128)); /* 262KHz */ + }else{ + if( usTranTime == 1) { /* time value が 1.0 ? */ + SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_512)); /* 65KHz */ + }else{ /* time value が 1.2〜2.5 のとき */ + SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_256)); /* 131KHz */ + } + } + } + break; + /*--- 1Mbit/s(one dat line) = 1MHz, の倍数のとき ---*/ + case CSD_TRAN_SPEED_1M: + if(usTranTime == 0x0001){ /* time value が 1.0 ? */ + SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_64)); /* 523KHz */ + } + else{ + if(usTranTime <= 0x0005){ /* time value が 2.0 以下? */ + SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_32)); /* 1.05MHz */ + } + else{ + if(usTranTime <= 0x0009){ /* time value が 4.0 以下? */ + SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_16)); /* 2.095MHz */ + }else{ /* time value が 4.5 以上のとき */ + SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_8)); /* 4.18MHz */ + } + } + } + break; + /*--- 10Mbit/s(one dat line) = 10MHz, の倍数のとき ---*/ + case CSD_TRAN_SPEED_10M: + if(usTranTime > 0x0004){ /* time value が 1.5 より大きい? */ + SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_2)); /* 16.76MHz */ + }else{ /* time value が 1.5 以下のとき */ + SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_4)); /* 8.38MHz */ + } + break; + /*--- 100Mbit/s(one dat line) = 100MHz, の倍数のとき ---*/ + case CSD_TRAN_SPEED_100M: /* time value がどんな値であっても */ + SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_2)); /* 16.76MHz */ + break; + default: + if( usTranSpeed != 7) { /* reserved値(=7)以外か? */ + SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_2)); /* 16.76MHz */ + } /* (松下drvでは、4以上なら288KHzにしている) */ + break; /* transfer rate unit が 7 のときは何もしない */ + } + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: SD_EnableClock + + Description: enable clock + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void SD_EnableClock( void) +{ + SD_OrFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_SDCLKEN)); +} + +/*---------------------------------------------------------------------------* + Name: SD_DisableClock + + Description: disable clock (for power save). + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void SD_DisableClock( void) +{ + SD_AndFPGA(SD_CLK_CTRL,(~SD_CLK_CTRL_SDCLKEN)); +} + + +/*---------------------------------------------------------------------------* + Name: SD_SelectBitWidth + + Description: set bus width for SD Card ( Not for MMC Card). + (The allowed data bus widths are given in SCR register.) + SDカードのDATラインバス幅を1bitまたは4bitに設定する。 + SDカードが4bitに対応していないか、MMCカードの場合はバス幅を4bitに + 設定することはできない。SDカードの許容するバス幅は、予め取得済みの + SCRレジスタによって参照している。 + + Arguments: b4bit : TRUE = 4bit, FALSE = 1bit + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +u16 SD_SelectBitWidth(s16 b4bit) +{ + /*--- カードの仕様(SCR)を参照 ---*/ +#if ADD_CHECK + if( b4bit){ /* SCRレジスタがリード済であること! */ + if( !(SD_SCR[0] & SCR_DAT_BUS_WIDTH_4BIT)) { /* カードが4bit幅に対応していないか? */ + b4bit = FALSE; /* 対応していない場合は1bit幅を指定しておく */ + } + }/*------------------------------*/ +#endif + /*--- 4bit(TRUE) 指定のとき ---*/ + if(b4bit){ + if(!SDCARD_MMCFlag){ /* MMCカードフラグ OFF?(ONなら何もしない) */ + if(SD_AppCommand()){ /* RCA設定後 CMD55発行 */ + return SDCARD_ErrStatus; /* CMD55が正常終了しなかったらエラー終了 */ + } + SD_SetFPGA(SD_ARG0,(0x0002)); /* Argument(1:0) = (10) to 4bit,(00) to 1bit */ + SD_SetFPGA(SD_ARG1,(0x0000)); /* Argument(31:2) = stuff bits */ + PRINTDEBUG( " ACMD6 (SET_BUS_WIDTH:4bit)\n"); + SD_Command(SD_CMD_ACMD | SET_BUS_WIDTH); /* ACMD6(ビット幅選択コマンド)発行、レスポンス(R1)待ち */ +#if ADD_CHECK + SD_CheckStatus(FALSE); /* コマンドレスポンス(R1)の Card Status チェック */ +#endif + if(!SDCARD_ErrStatus){ /* エラーなし? */ + SD_AndFPGA(SD_OPTION,(~SD_OPTION_WIDTH_1BIT)); /* IPにビット幅の設定(4bit幅) */ + } + } + }/*--- 1bit(FALSE) 指定のとき ---*/ + else{ + if(!SDCARD_MMCFlag){ /* MMCカードフラグ OFF?(ONなら何もしない) */ + if(SD_AppCommand()){ /* RCA設定後 CMD55発行処理 */ + return SDCARD_ErrStatus; /* CMD55が正常終了しなかったらエラー終了 */ + } + SD_SetFPGA(SD_ARG0,(0x0000)); /* Argument(1:0) = bus width : 1bit */ + SD_SetFPGA(SD_ARG1,(0x0000)); /* Argument(31:2) = stuff bits */ + PRINTDEBUG( " ACMD6 (SET_BUS_WIDTH:1bit)\n"); + SD_Command(SD_CMD_ACMD | SET_BUS_WIDTH); /* ACMD6(ビット幅選択コマンド)発行、レスポンス(R1)待ち */ +#if ADD_CHECK + SD_CheckStatus(FALSE); /* コマンドレスポンス(R1)の Card Status チェック */ +#endif + } + if(!SDCARD_ErrStatus){ /* エラーステータスの確認(エラー無し?) */ + SD_OrFPGA(SD_OPTION,(SD_OPTION_WIDTH_1BIT)); /* IPにビット幅の設定(1bit幅) */ + } + }/*------------------------------*/ + + return SDCARD_ErrStatus; +} + + +/*---------------------------------------------------------------------------* + Name: MMCP_WriteBusWidth + + Description: set bus width for SD Card ( Not for MMC Card). + (The allowed data bus widths are given in SCR register.) + MMCplusカードのDATラインバス幅を1bitまたは4bitに設定する。 + SDまたはMMCカードの場合はバス幅を4bitに設定することはできない。 + + Arguments: b4bit : TRUE = 4bit, FALSE = 1bit + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +u16 MMCP_WriteBusWidth(s16 b4bit) +{ + if( !SDCARD_MMCFlag) { + return 1; + } + + /* 書き込み開始オフセット設定 */ + if( b4bit) { + SD_SetFPGA(SD_ARG0,(0x0100)); /* Argument(15:8)=(0x1) to 4bit,(0x0) to 1bit */ + }else{ + SD_SetFPGA(SD_ARG0,(0x0000)); /* Argument(15:8)=(0x1) to 4bit,(0x0) to 1bit */ + } + SD_SetFPGA(SD_ARG1,(0x03B7)); /* Argument(25:24)=(0x3)Write, (23:16)=(183)Index */ + + /* CMD6(ビット幅選択コマンド)発行、レスポンス(R1)待ち */ + SD_Command(SD_CMD_CMD | EXT_CSD_ACCESS); + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: MMCP_BusTest + + Description: バスのテストを行う。 + この後カードにDATライン経由でデータを送信する必要がある。 + + Arguments: readflag : リード時TRUE, ライト時FALSE + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +u16 MMCP_BusTest( BOOL readflag) +{ + /**/ + SD_TransReadyFPGA(); /* INFOレジスタ初期化 */ + SD_AndFPGA(SD_INFO2_MASK,(~SD_INFO2_MASK_BWE)); /* SDカードからのデータ書込み要求割込み許可 */ + + /**/ + SD_SetFPGA( SD_ARG0, 0); + SD_SetFPGA( SD_ARG1, 0); + + if( readflag) { + SD_TransCommand( 14); + }else{ + SD_TransCommand( 19); + } + + return( SDCARD_ErrStatus); +} + + +/*---------------------------------------------------------------------------* + Name: SD_FPGA_irq + + Description: handler of data transfer request interrupt from card, + check and clear interrupt register of IP. + カードからの転送要求(BREまたはBWE)割り込み発生時に + どちらかを調べて返し、INFO2の当該割り込み要求フラグをクリアする。 + + Arguments: None + + Returns: TRUE : BRE割り込み発生 + FALSE : BWE割り込み発生 + *---------------------------------------------------------------------------*/ +s16 SD_FPGA_irq(void) +{ + /*--- FIFOを使うとき ---*/ + if( SDCARD_UseFifoFlag) { + if( SD_CheckFPGAReg( *SDIF_CNT_L, (u16)SDIF_CNT_FFIE)) { /* FULL割り込み許可のとき */ + return TRUE; + }else{ + if(!SD_CheckFPGAReg(SD_INFO2_MASK,SD_INFO2_MASK_BWE)){ /* SDカードからのデータ書込み要求あり? */ + SD_AndFPGA(SD_INFO2,(~SD_INFO2_BWE)); /* SD用バッファ制御 Write Enable リセット*/ + } + return FALSE; + } + }else{ /*--- FIFOを使わないとき ---*/ + if(!SD_CheckFPGAReg(SD_INFO2_MASK,SD_INFO2_MASK_BRE)){ /* SDカードからのデータ読出し要求あり? */ + SD_AndFPGA(SD_INFO2,(~SD_INFO2_BRE)); /* SD用バッファ制御 Read Enable リセット*/ + return TRUE; + } + if(!SD_CheckFPGAReg(SD_INFO2_MASK,SD_INFO2_MASK_BWE)){ /* SDカードからのデータ書込み要求あり? */ + SD_AndFPGA(SD_INFO2,(~SD_INFO2_BWE)); /* SD用バッファ制御 Write Enable リセット*/ + return FALSE; + } + } + return FALSE; +} + +/*---------------------------------------------------------------------------* + Name: SD_StopTransmission + + Description: manual send CMD12 to terminate translate. + 手動でCMD12を発行し、転送終了をFPGAに通知する + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void SD_StopTransmission(void) +{ + SD_OrFPGA(SD_STOP,(SD_STOP_STP)); /* データ転送終了設定 */ +} + +/*---------------------------------------------------------------------------* + Name: SD_TransEndFPGA + + Description: clear the transfer interrupt. + カード転送終了時に転送関連の割り込みを禁止に戻しておく + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void SD_TransEndFPGA(void) +{ + SD_OrFPGA(SD_INFO2_MASK,(SD_INFO2_MASK_ALLERRMASK)); /* SD Card I/F の 全エラー割込み禁止 */ + SD_OrFPGA(SD_INFO1_MASK,(SD_INFO1_MASK_ALL_END)); /* R/W アクセス終了割込み禁止 */ + + if(!SD_CheckFPGAReg(SD_INFO2_MASK,SD_INFO2_MASK_BRE)){ /* SDカードからのデータ読込み要求割込み許可か? */ + SD_OrFPGA(SD_INFO2_MASK,(SD_INFO2_MASK_BRE)); /* SDカードからのデータ読込み要求割込み禁止 */ + } + if(!SD_CheckFPGAReg(SD_INFO2_MASK,SD_INFO2_MASK_BWE)){ /* SDカードからのデータ書込み要求割込み許可か? */ + SD_OrFPGA(SD_INFO2_MASK,(SD_INFO2_MASK_BWE)); /* SDカードからのデータ書込み要求割込み禁止 */ + } +} + +/*---------------------------------------------------------------------------* + Name: SD_CheckStatus + + Description: check the card status in the R1. + R1レスポンスのカードステータスをチェックする + + Arguments: bRead : 読み込み処理時 = TRUE + + Returns: 0 : success + >0 : error + *---------------------------------------------------------------------------*/ +u16 SD_CheckStatus(BOOL bRead) +{ + /* コマンドレスポンス(R1)の[39:8] から Card status を取得 */ + SD_GetFPGA((((LELONG *)&SDCARD_Status)->dt2word.low),SD_RSP0); + SD_GetFPGA((((LELONG *)&SDCARD_Status)->dt2word.high),SD_RSP1); + + /*--- 松下サンプルドライバでやっている処理 ---*/ + if(bRead){ /* リード時か? */ + if(!(SDCARD_ErrStatus & SDMC_ERR_TIMEOUT)){ /* タイムアウト発生していないか? */ + SDCARD_Status &= ~SDCARD_STATUS_OUT_OF_RANGE; /* OUT_OF_RANGEフラグを落とす */ + } + }/*-------------------------------------------*/ + + PRINTDEBUG( " SD_CheckStatus ======== 0x%x\n", SDCARD_Status); + + if(SDCARD_Status & RSP_R1_STATUS_ERR){ /* コマンドレスポンス(R1)のカードステータスがエラーか確認 */ + SD_SetErr(SDMC_ERR_R1_STATUS); /* コマンドレスポンス(R1)のカードステータス エラー */ + } + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: SD_SwapByte + + Description: swap bytes in a 16bit data. + 16bitデータの上位と下位を入れ換える + + Arguments: data : 16bit data + + Returns: swapped data + *---------------------------------------------------------------------------*/ +u16 SD_SwapByte(u16 *data) +{ + u16 usDATA; + + usDATA = *data; + usDATA = (u16)(((usDATA & 0x00FF) << 8) | ((usDATA & 0xFF00) >> 8)); + + return usDATA; +} + +/*---------------------------------------------------------------------------* + Name: SD_EnableSeccnt + + Description: enable SD_SECCNT register. + SD_SECCNT を有効化して値をセットする。 + + Arguments: ulSDCARD_SectorCount : セクタカウント値(1セクタ=512byte) + + Returns: None + *---------------------------------------------------------------------------*/ +void SD_EnableSeccnt( u32 ulSDCARD_SectorCount) +{ + u16 usSector; + + usSector = (u16)ulSDCARD_SectorCount; + SD_OrFPGA(SD_STOP,SD_STOP_SEC_ENABLE); /* SD_SECCNTレジスタを有効にする */ + SD_SetFPGA(SD_SECCNT,usSector); /* SD_SECCNTレジスタに転送セクタカウントを設定 */ +} + +/*---------------------------------------------------------------------------* + Name: SD_DisableSeccnt<現在は未使用関数> + + Description: disable SD_SECCNT register. + SD_SECCNT を無効化する。 + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void SD_DisableSeccnt( void) +{ + u16 i; + + /*--- 松下ドライバでやっていること ---*/ + for ( i=0; i<50000; i++) /* カウント値50000では足りないことあり */ + { /* SD_INFO1レジスタの R/W access all end 待ち */ + if(SD_CheckFPGAReg(SD_INFO1,SD_INFO1_ALL_END)) { + break; + } + }/*-----------------------------------*/ + SD_AndFPGA(SD_STOP,(~SD_STOP_SEC_ENABLE)); /* SD_SECCNTレジスタを無効にする */ +} + +/*---------------------------------------------------------------------------* + Name: SD_SetErr + + Description: set error flag + 指定のエラーフラグをセットする + + Arguments: Error : error flag to set + + Returns: None + *---------------------------------------------------------------------------*/ +void SD_SetErr(u16 Error) +{ + OSIntrMode irq_core_flag; + +#if (TARGET_OS_CTR == 1) + irq_core_flag = osDisableInterrupts(); /* 割込み禁止 */ + SDCARD_ErrStatus |= Error; /* エラーステータスを設定 */ + osRestoreInterrupts( irq_core_flag); /* 割り込み設定を元に戻す */ +#else + irq_core_flag = OS_DisableInterrupts(); + SDCARD_ErrStatus |= Error; /* エラーステータスを設定 */ + OS_RestoreInterrupts( irq_core_flag); +#endif +} + +/*---------------------------------------------------------------------------* + Name: SD_ClrErr + + Description: clear error flag + 指定のエラーフラグをクリアする + + Arguments: Error : error flag to clear + + Returns: None + *---------------------------------------------------------------------------*/ +void SD_ClrErr(u16 Error) +{ + OSIntrMode irq_core_flag; + +#if (TARGET_OS_CTR == 1) + irq_core_flag = osDisableInterrupts(); /* 割込み禁止 */ + SDCARD_ErrStatus &= ~(Error); /* エラーステータスをクリア */ + osRestoreInterrupts( irq_core_flag); /* 割り込み設定を元に戻す */ +#else + irq_core_flag = OS_DisableInterrupts(); /* 割込み禁止 */ + SDCARD_ErrStatus &= ~(Error); /* エラーステータスをクリア */ + OS_RestoreInterrupts( irq_core_flag); /* 割り込み設定を元に戻す */ +#endif +} + + +/*---------------------------------------------------------------------------* + Name: SD_TransReadyFPGA + + Description: setup for the command that the card will response and request data transfer. + DATラインでのデータ転送が発生するコマンド発行前の転送準備 + (BRE, BWE割り込みの許可は別途行うこと) + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void SD_TransReadyFPGA(void) +{ + /* 関連レジスタ初期化 */ + SD_AndFPGA(SD_INFO2,(~SD_INFO2_ERR_ALLCLR)); /* SD Card I/F の 全てのエラーをクリア */ + SD_AndFPGA(SD_INFO1,(~(SD_INFO1_RES_END | SD_INFO1_ALL_END))); /* SD_INFO1レジスタの Response end と access all end クリア */ + SD_AndFPGA(SD_INFO2,(~SD_INFO2_BRE)); /* SD用バッファ制御 Read Enable クリア*/ + SD_AndFPGA(SD_INFO2,(~SD_INFO2_BWE)); /* SD用バッファ制御 Write Enable クリア*/ + SD_AndFPGA(SD_STOP,(~SD_STOP_STP)); /* データ転送終了クリア */ + + /* 割り込み関連許可 */ + SD_AndFPGA(SD_INFO2_MASK,(~SD_INFO2_MASK_ALLERRMASK)); /* SD Card I/F の 全エラー割込み許可 */ + SD_AndFPGA(SD_INFO1_MASK,(~SD_INFO1_MASK_ALL_END)); /* R/W access all end 割込み許可(Responseはポーリングで見るため許可しない) */ +} + + +/*---------------------------------------------------------------------------* + Name: SD_TransCommand + + Description: send command that the card will response and request data transfer. + コマンドを送出する(DATラインでのデータ転送が発生するコマンド用) + + Arguments: ucCommand : command number + + Returns: 0 : success + >0 : error + *---------------------------------------------------------------------------*/ +u16 SD_TransCommand(u16 ucCommand) +{ + SD_SetFPGA(SD_CMD,(ucCommand)); /* コマンド発行 */ + + while(!SD_CheckFPGAReg(SD_INFO1,SD_INFO1_RES_END)){ /* Response end 待ち */ + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ + break; + } + } + SD_CheckStatus(FALSE); /* R1レスポンスのcard statusチェック*/ + + if(SDCARD_ErrStatus & SDMC_ERR_R1_STATUS){ + SD_StopTransmission(); /* カード転送終了をFPGAに通知 */ + } + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: SD_CheckFPGAReg + + Description: check register bits. + レジスタの状態をチェックする + + Arguments: reg : 16bit register data + value : mask data + + Returns: TRUE : some of mask data bits are 1 on the register. + FALSE : no mask data bits is 1 on the register. + *---------------------------------------------------------------------------*/ +BOOL SD_CheckFPGAReg(u16 reg,u16 value) +{ + if( reg & value) { + return TRUE; + }else{ + return FALSE; + } +} + +/*---------------------------------------------------------------------------* + Name: SD_SendNumWRSectors + + Description: send "number of well written blocks" command (for SD card only). + SDカード専用方式でのライト済みセクタ数取得コマンド発行。この後カードは + DATライン経由で1ブロック(4Bytesに設定しておくこと)送信してくる。 + MultiBlock R/W と異なり、DATライン経由で転送されてくるSDカードの + レジスタは、MSBから先に送られてくることに注意。 + (Physical Layer Specification 2.00 p12-13参照) + + Arguments: None + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +u16 SD_SendNumWRSectors(void) +{ + PRINTDEBUG( " ACMD22 (SEND_NUM_WR_SECTORS)\n"); + /* Argument(31:0) = stuff bits */ + SD_TransReadyFPGA(); /* 関連レジスタ初期化 */ + SD_AndFPGA(SD_INFO2_MASK,(~SD_INFO2_MASK_BRE)); /* SDカードからのデータ読込み要求割込み許可 */ + + SD_TransCommand((SD_CMD_ACMD | SEND_NUM_WR_SECTORS)); /* ACMD22(書きこみ完了セクタ数取得コマンド)発行、レスポンス(R1)待ち */ + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: SD_MultiWriteBlock + + Description: send multiple block write command. + マルチブロックライトコマンド発行。この後カードに + DATライン経由でデータを送信する必要がある。 + + Arguments: ulOffset : offset address to write(BYTE). + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +u16 SD_MultiWriteBlock(u32 ulOffset) +{ + PRINTDEBUG( " CMD25 (WRITE_MULTIPLE_BLOCK)\n"); + + SD_TransReadyFPGA(); /* INFOレジスタ初期化 */ +// if( !SDCARD_UseFifoFlag) { /* FIFOを使わないとき */ + SD_AndFPGA(SD_INFO2_MASK,(~SD_INFO2_MASK_BWE)); /* SDカードからのデータ書込み要求割込み許可 */ +// } + + /* 書き込み開始オフセット設定 */ + SD_SetFPGA(SD_ARG0,(((LELONG *)&ulOffset)->dt2word.low)); + SD_SetFPGA(SD_ARG1,(((LELONG *)&ulOffset)->dt2word.high)); + + SD_TransCommand(WRITE_MULTIPLE_BLOCK); /* CMD25(マルチセクタライトコマンド)発行 */ + + return SDCARD_ErrStatus; +} + + diff --git a/build/libraries/devices/rom_sdmc/ARM7/sdif_ip.h b/build/libraries/devices/rom_sdmc/ARM7/sdif_ip.h new file mode 100644 index 0000000..96493b4 --- /dev/null +++ b/build/libraries/devices/rom_sdmc/ARM7/sdif_ip.h @@ -0,0 +1,349 @@ +/* +** Copyright (c) 2000-2001 Matsushita Electric Industrial Co., Ltd. +** All Rights Reserved. +*/ + +/* +** $Module SDカードアクセスモジュール・インクルード +** $Filename SD_CARD_IP.H +** $Version 1.0 版 +** $Date 01/02/16 +** $Log 01/02/16 rev1.0作成 +** 松下電器産業(株)半導体開発本部 +*/ + + +#ifndef __SD_CARD_IP_H__ +#define __SD_CARD_IP_H__ + +//#define IO3 0 /* Insert Remove SW = FALSE IO3 = TRUE */ + +//#define MAX_SD_CLOCK_4M 0 /* MAX SD Clock 4.608MHz */ +//#define MAX_SD_CLOCK_9M 1 /* MAX SD Clock 9.216MHz */ + + +/*--------------------------------------------- + ラッパーレジスタのビット制御(フラグ定義) +---------------------------------------------*/ +/* SD_CNTレジスタ */ +#define SDIF_CNT_USEDTC (0x0001) /* DTC使用フラグ (R/W) */ +#define SDIF_CNT_USEFIFO (0x0002) /* FIFO使用フラグ (R/W) */ +#define SDIF_CNT_FULL (0x0100) /* FIFO FULLフラグ (RO) */ +#define SDIF_CNT_NEMP (0x0200) /* FIFO NOT EMPTYフラグ (RO) */ +#define SDIF_CNT_FCLR (0x0400) /* FIFO クリアフラグ (WO) */ +#define SDIF_CNT_FFIE (0x0800) /* FIFO FULLで割り込み (R/W) */ +#define SDIF_CNT_FEIE (0x1000) /* FIFO EMPTYで割り込み (R/W) */ + +#define SDCARD_UseFifoFlag ((*SDIF_CNT) & SDIF_CNT_USEFIFO) + +/*------------------------------------- +レジスタのビット制御(フラグ定義) +-------------------------------------*/ +/* SD_CMDレジスタ*/ +#define SD_CMD_CMD 0x0000 /* SDカードへの通常アクセス(CMD) */ +#define SD_CMD_ACMD 0x0040 /* SDカードへのセキュリティアクセス(ACMD) */ + +/* SD_STOPレジスタ */ +#define SD_STOP_STP 0x0001 /* データ転送終了を知らせる */ +#define SD_STOP_SEC_ENABLE 0x0100 /* SD_SECCNTレジスタ有効(セクタカウントレジスタ) */ + +/* SD_SECCNTレジスタ */ +#define SD_SECCNT_END 0x0000 /* SD_SECCNTレジスタ カウントチェック */ + +/* SD_SIZEレジスタ */ +#define SD_SIZE_DATA_LENGTH_1B 0x0001 /* SDカード転送データサイズ 1Bytes */ +#define SD_SIZE_DATA_LENGTH_2B 0x0002 /* SDカード転送データサイズ 2Bytes */ +#define SD_SIZE_DATA_LENGTH_4B 0x0004 /* SDカード転送データサイズ 4Bytes */ +#define SD_SIZE_DATA_LENGTH_8B 0x0008 /* SDカード転送データサイズ 8Bytes (SCR) */ +#define SD_SIZE_DATA_LENGTH_16B 0x0010 /* SDカード転送データサイズ 16Bytes */ +#define SD_SIZE_DATA_LENGTH_32B 0x0020 /* SDカード転送データサイズ 32Bytes */ +#define SD_SIZE_DATA_LENGTH_64B 0x0040 /* SDカード転送データサイズ 64Bytes (SD_Status) */ +#define SD_SIZE_DATA_LENGTH_128B 0x0080 /* SDカード転送データサイズ 128Bytes */ +#define SD_SIZE_DATA_LENGTH_256B 0x0100 /* SDカード転送データサイズ 256Bytes */ +#define SD_SIZE_DATA_LENGTH_512B 0x0200 /* SDカード転送データサイズ 512Bytes (データ) */ + +/* SD_OPTIONレジスタ */ +#define SD_OPTION_WIDTH_1BIT 0x8000 /* ビット幅の選択 1bit幅 */ +#define SD_OPTION_MSEL_C2NOUSE 0x4000 /* C2モジュール未使用 */ +#define SD_CD_DETECT_TIME 0xFFF0 /* CD 検出タイムだけをクリアするためのマスク */ + +/* SD_INFO2レジスタ */ +#define SD_INFO2_ERR_ILA 0x8000 /* イリーガルアクセスエラー */ +#define SD_INFO2_BWE 0x0200 /* SDカードから512byteのデータ書込み要求 */ +#define SD_INFO2_BRE 0x0100 /* SDカードから512byteのデータ読込み要求 */ +#define SD_INFO2_ERR_ALLCLR 0x807F /* SD Card エラーレジスタクリア */ +#define SD_INFO2_ERR_SDDAT0 0x0080 /* SD Card Busy bit */ +#define SD_INFO2_ERR_RESTIMEOUT 0x0040 /* レスポンスタイムアウトエラー */ +#define SD_INFO2_ERR_UNDERFLOW 0x0020 /* FIFO アンダーフローエラー */ +#define SD_INFO2_ERR_OVERFLOW 0x0010 /* FIFO オーバーフローエラー */ +#define SD_INFO2_ERR_TIMEOUT 0x0008 /* レスポンス以外のタイムアウトエラー */ +#define SD_INFO2_ERR_END 0x0004 /* フレーム終了認識できないときの(END)エラー */ +#define SD_INFO2_ERR_CRC 0x0002 /* CRC エラー */ +#define SD_INFO2_ERR_CMD 0x0001 /* CMDエラー */ + +#define SD_INFO2_RW_SET 0x0300 /* SDカード Read/Write 要求割込み要因チェック */ +#define SD_INFO2_ERROR_SET 0x807F /* SDカード エラー割込み要因チェック */ + +/* SD_INFO2_MASKレジスタ */ +#define SD_INFO2_MASK_ILA 0x8000 /* イリーガルアクセスエラー割込みマスク */ +#define SD_INFO2_MASK_BWE 0x0200 /* SDカードからのデータ書込み要求割込み禁止 */ +#define SD_INFO2_MASK_BRE 0x0100 /* SDカードからのデータ読込み要求割込み禁止 */ +#define SD_INFO2_MASK_ALLERRMASK 0x807F /* 全エラー割り込み禁止 */ +#define SD_INFO2_MASK_EXCEPT_OVERFLOW 0x802F /* 全エラー割り込み禁止 FIFO Overflow Errorを除く */ +#define SD_INFO2_MASK_RESTIMEOUT 0x0040 /* Time out 割込みEnable */ +#define SD_INFO2_MASK_UNDERFLOW 0x0020 /* FIFO アンダーフロー 割込みEnable */ +#define SD_INFO2_MASK_OVERFLOW 0x0010 /* FIFO オーバーフロー 割込みEnable */ +#define SD_INFO2_MASK_TIMEOUT 0x0008 /* Time out 割込みEnable */ +#define SD_INFO2_MASK_END 0x0004 /* END エラー 割込みEnable */ +#define SD_INFO2_MASK_CRC 0x0002 /* CRC エラー 割込みEnable */ +#define SD_INFO2_MASK_CMD 0x0001 /* CMD エラー 割込みEnable */ +#define SD_INFO2_MASK_ERRSET 0x807F /* SDカード エラー割込み要因チェック */ + +/* SD_INFO1レジスタ */ +#define SD_INFO1_DAT3DETECT 0x0400 /* (IO3検出) card detect(検出=1) : CTRでは使用できない*/ +#define SD_INFO1_DAT3INSERT 0x0200 /* (IO3検出) card inserted(挿入=1) : CTRでは使用できない */ +#define SD_INFO1_DAT3REMOVE 0x0100 /* (IO3検出) card removed(抜け=1) : CTRでは使用できない */ +#define SD_INFO1_DAT3INIT 0x0300 /* (IO3検出) の初期化 */ +#define SD_INFO1_WRITEPROTECT 0x0080 /* write protect(書き込み禁止=1) */ +#define SD_INFO1_DETECT 0x0020 /* card detect(検出=1) */ + +#define SD_INFO1_INSERT 0x0010 /* card inserted(挿入=1) */ +#define SD_INFO1_REMOVE 0x0008 /* card removed(抜け=1) */ + +#define SD_INFO1_ALL_END 0x0004 /* R/W access all end */ +#define SD_INFO1_RES_END 0x0001 /* Response end */ +#define SD_INFO1_INIT 0x0005 /* SD Cardの状態を初期化 */ + +#define SD_INFO1_SET 0x031D /* SDカード 挿抜 and RWアクセス終了 and レスポンス終了 要求割込み要因チェック */ + +/* SD_INFO1_MASKレジスタ (0:割り込み許可、1:割り込み禁止)*/ +#define SD_INFO1_MASK_DAT3INSERT 0x0200 /* (IO3検出) card inserted(挿入) 割込み禁止 */ +#define SD_INFO1_MASK_DAT3REMOVE 0x0100 /* (IO3検出) card removed(抜け) 割込み禁止 */ +#define SD_INFO1_MASK_INSERT 0x0010 /* card inserted(挿入) 割込み禁止 */ +#define SD_INFO1_MASK_REMOVE 0x0008 /* card removed(抜け) 割込み禁止 */ +#define SD_INFO1_MASK_ALL_END 0x0004 /* R/W access all end 割込み禁止 */ +#define SD_INFO1_MASK_RES_END 0x0001 /* Response end 割込み禁止 */ + +/* CC_EXT_MODEレジスタ */ +#define CC_EXT_MODE_PIO 0x0000 /* PIOモード */ +#define CC_EXT_MODE_DMA 0x0002 /* DMAモード */ + +/* SOFT_RSTレジスタ */ +#define SOFT_RST_SDIF_RST 0x0001 /* SD I/Fモジュールをリセット */ + +/* SD_CLK_CTRLレジスタ */ +#define SD_CLK_CTRL_SDCLKEN 0x0100 /* SDカードクロック出力イネーブル */ +#define SD_CLK_CTRL_512 0x0180 /* SDクロックの周波数(分周比512)*/ +#define SD_CLK_CTRL_256 0x0140 /* SDクロックの周波数(分周比256)*/ +#define SD_CLK_CTRL_128 0x0120 /* SDクロックの周波数(分周比128)*/ +#define SD_CLK_CTRL_64 0x0110 /* SDクロックの周波数(分周比 64)*/ +#define SD_CLK_CTRL_32 0x0108 /* SDクロックの周波数(分周比 32)*/ +#define SD_CLK_CTRL_16 0x0104 /* SDクロックの周波数(分周比 16)*/ +#define SD_CLK_CTRL_8 0x0102 /* SDクロックの周波数(分周比 8)*/ +#define SD_CLK_CTRL_4 0x0101 /* SDクロックの周波数(分周比 4)*/ +#define SD_CLK_CTRL_2 0x0100 /* SDクロックの周波数(分周比 2)*/ + + +/*------------------------------------- +マルチポート対応ビット制御(フラグ定義) +-------------------------------------*/ +#define SDCARD_PORT_NO 0x0300 /* カードポート選択数 */ +#define SDCARD_PORT_NO_MAX 0x04//0x02 /* カードポート最大選択数 */ +#define SDCARD_PORT_NO_MIN 0x01 /* カードポート最小選択数 */ +#define SDCARD_PORT_SELECT_NO 0x0001 /* カードポート番号ビット */ +#define SDCARD_PORT0 0x0000 /* カードポート番号ビット */ +#define SDCARD_PORT1 0x0001 /* カードポート番号ビット */ + +/* EXT_WPレジスタ(ポート1以降のライトプロテクト) */ +#define EXT_WP_PORT1 0x0001 /* ポート1write protect(書き込み禁止=1)*/ + +/* EXT_CDレジスタ */ +#define EXT_CD_PORT1_REMOVE 0x0001 /* ポート1 card detect(検出=1) */ +#define EXT_CD_PORT1_INSERT 0x0002 /* ポート1 card inserted(挿入=1) */ +#define EXT_CD_PORT1_DETECT 0x0004 /* ポート1 card removed(抜け=1) */ + +/* EXT_CD_DAT3レジスタ */ +//#define EXT_CD_PORT1_DAT3INIT 0x0003 /* ポート1 card の状態 (IO3検出) の初期化 */ +#define EXT_CD_PORT1_DAT3REMOVE 0x0001 /* ポート1 dat3 card detect(検出=1) */ +#define EXT_CD_PORT1_DAT3INSERT 0x0002 /* ポート1 dat3 card inserted(挿入=1) */ +#define EXT_CD_PORT1_DAT3DETECT 0x0004 /* ポート1 dat3 card removed(抜け=1) */ + +/* EXT_CD_DAT3_MASKレジスタ */ +#define EXT_CD_MASK_PORT1INSERT 0x0002 /* port1 card inserted(挿入) 割込み禁止 */ +#define EXT_CD_MASK_PORT1REMOVE 0x0001 /* port1 card removed(抜け) 割込み禁止 */ +#define EXT_CD_MASK_PORT1DAT3INSERT 0x0002 /* port1 (IO3検出) card inserted(挿入) 割込み禁止 */ +#define EXT_CD_MASK_PORT1DAT3REMOVE 0x0001 /* port1 (IO3検出) card removed(抜け) 割込み禁止 */ + +/*------------------------------------- +カードの選択 +--------------------------------------*/ +#define SDCARD_DETECT_VISUAL_BIT 0x0400 /*** upper layer card detected visual bit ***/ + +/*------------------------------------- +ライトプロテクト +-------------------------------------*/ +#define SDCARD_WP_PERMANENT_BIT 0x0020 /*** permanent write protection ***/ +#define SDCARD_WP_TEMPORARY_BIT 0x0010 /*** temporary write protection ***/ + +/*------------------------------------- +SD or MMCカードコマンド +-------------------------------------*/ +#define GO_IDLE_STATE (0) /* resets all cards to idle state */ +#define SEND_OP_COND (1) /* Asks all cards in idle state to send their operation conditions */ +#define ALL_SEND_CID (2) /* send CID numbers */ +#define SEND_RELATIVE_ADDR (3) /* ask the card to publish a new relative address(RCA) */ +#define SET_BUS_WIDTH (6) /* ビット幅の選択 */ +#define SELECT_CARD (7) /* Command toggles acard between thr Stand-by and Transfer states */ +#define SEND_CSD (9) /* addressed card sends its card-specific data(CSD) */ +#define STOP_TRANSMISSION (12) /* forces the card to stop transmission */ +#define SD_SEND_STATUS (13) /* addressed card sends its status register */ +#define SET_BLOCKLEN (16) /* sets the block length */ +#define READ_MULTIPLE_BLOCK (18) /* マルチブロックリード */ +#define WRITE_MULTIPLE_BLOCK (25) /* マルチブロックライト */ +#define APP_CMD (55) /* CMD55 */ +#define SD_STATUS (13) /* ACMD13 Send the SD_CARD status */ +#define SEND_NUM_WR_SECTORS (22) /* ACMD22 書きこみ完了セクタ数取得 */ +#define SD_APP_OP_COND (41) /* ACMD41 */ +#define SEND_SCR (51) /* SD configuration register (SCR) */ + +/* MMCplus, eMMCの定義 */ +#define EXT_CSD_ACCESS (6) + +/* Extended Commandの定義 */ +#define EXT_NORMAL (0) +#define EXT_SDIO (0x4000) + +#define EXT_COM_R3 (0x0700) + +#define EXT_CMD (0x00C0) + +#define SEND_IF_COND (8) /* Physical Layer 2.0 で追加されたコマンド */ +#define SEND_IF_COND_EXT (EXT_SDIO | EXT_COM_R3 | EXT_CMD | SEND_IF_COND) + + +/*------------------------------------- +IP レジスタアクセス マクロ関数 +-------------------------------------*/ +#define SD_OrFPGA(reg,value) ((reg) |= (value)); +#define SD_AndFPGA(reg,value) ((reg) &= (value)); +#define SD_SetFPGA(reg,value) ((reg) = (value)); +#define SD_GetFPGA(dest,reg) ((dest) = (reg)); + +/*********************************************************************** + 構造体定数 +***********************************************************************/ +typedef union{ + u32 dat; + struct { + u16 low; + u16 high; + } dt2word; +} LELONG; + +/*------------------------------------- +その他(ビット制御) +-------------------------------------*/ +#define RSP_R3_OCR31 0x8000 /* Use OCR Busy bit Check */ +#define RSP_R3_OCR_VDD 0x0030 /* Use OCR VDD bit Check (3.2-3.3v,3.3-3.4v is OK)*/ + +/*--- SCR[0]に対する4bitバス幅対応フラグのマスク ---*/ +//SCRのbit50に相当するが、SCRとSD_STATUSはMSBから送られてくることを考慮してある +#define SCR_DAT_BUS_WIDTH_4BIT 0x0400 /* SCR DAT Bus width supported 4bit */ + +/*--- 127bitCSD (CSD[0]〜CSD[7])関連 ---*/ +#define CSD_VDD_R_CURR_MIN 0x0038 /* "VDD_R_CURR_MIN" (for CSD[3]) */ +#define CSD_VDD_R_CURR_MAX 0x0007 /* "VDD_R_CURR_MAX" (for CSD[3]) */ +#define CSD_VDD_W_CURR_MIN 0xE000 /* "VDD_W_CURR_MIN" (for CSD[2]) */ +#define CSD_VDD_W_CURR_MAX 0x1C00 /* "VDD_W_CURR_MAX" (for CSD[2]) */ + +#define CSD_READ_BL_LEN 0x0F00 /* "READ_BL_LEN" (for CSD[4])*/ +#define CSD_WRITE_BL_LEN_BIT_25_24 0x0003 /* "WRITE_BL_LEN" (for CSD[1])*/ +#define CSD_WRITE_BL_LEN_BIT_23_22 0xC000 /* "WRITE_BL_LEN" (for CSD[0]*/ +#define CSD_READ_BL_PARTIAL 0x0080 /* "READ_BL_PARTIAL" (for CSD[4]) */ +#define CSD_TRANSFER_RATE 0x0700 /* "Transfer rate unit" of "TRAN_SPEED" (for CSD[5]) */ +#define CSD_TRAN_SPEED_100K 0x0000 /* 100Kbit/s (for CSD Transfer rate) */ +#define CSD_TRAN_SPEED_1M 0x0001 /* 1Mbit/s (for CSD Transfer rate) */ +#define CSD_TRAN_SPEED_10M 0x0002 /* 10Mbit/s (for CSD Transfer rate) */ +#define CSD_TRAN_SPEED_100M 0x0003 /* 100Mbit/s (for CSD Transfer rate) */ +#define CSD_TRAN_SPEED_OTHER 0x0004 /* Reserve (for CSD Transfer rate) */ + +#define CSD_C_SIZE_MULT 0x0380 /* RSP2 の bit[49:47] */ +#define CSD_C_SIZE_BIT_73_72 0x0003 /* RSP3 の bit[73:72](C_SIZE) */ +#define CSD_C_SIZE_BIT_71_62 0xFFC0 /* RSP3 の bit[71:62](C_SIZE) */ +//SDHC(CSD format version2)の場合 +#define CSD_C_SIZE_BIT_69_56 0x3FFF /* SD_CSD[3] */ +#define CSD_C_SIZE_BIT_55_48 0xFF00 /* SD_CSD[2] */ + +#define CSD_STRUCT_BIT_127_126 0x00C0 /* SD_CSD[7] */ + +//#define VDD_R_CURR_MIN 0x0000 /* CSD max read current@VDD min */ +//#define VDD_R_CURR_MAX 0x0007 /* CSD max read current@VDD max */ +//#define VDD_W_CURR_MIN 0x0000 /* CSD max write current@VDD min */ +//#define VDD_W_CURR_MAX 0x0007 /* CSD max write current@VDD max */ + +/*--- R1レスポンスの card status(32bit)に対するマスク ---*/ +#define RSP_R1_STATUS_ERR 0xF9FF0008 /* R1(レスポンス)のカードステータスのチェック */ +#define SDCARD_STATUS_OUT_OF_RANGE 0x80000000 /* Card Status OUT_OF_RANGE のチェック */ +#define RSP_R1_CURRENT_STATE 0x1E00 /* CARD current state */ +/*-------------------------------------------------------*/ + +/* レスポンスのRSP0 & RSP_R1_CURRENT_STATEを1ビット右シフトした値に対するフラグ */ +#define CURRENT_STATE_DATA 0x0500 /* CARD current state data */ +#define CURRENT_STATE_RCV 0x0600 /* CARD current state rcv */ + +/* カードステータス */ +#define SD_MEMORY_CARD 0x00FF /* SD_CARD_TYPE SD memory card */ + + +/*------------------------------------- +プロトタイプ宣言 +-------------------------------------*/ +void SD_Init(void); /* SD Cardインターフェース部をリセット&初期設定 */ +void SD_EnableInfo(void); /* SD Card 挿抜 割り込みイネーブル・ディスエーブル */ +u16 SD_Command(u16 ucCommand); /* SDカードコマンド送出 */ +u16 SD_AppCommand(void); /* SDカード RCA = 1をセット後 CMD55 発行 */ +u16 SD_AppOpCond(void); /* ACMD41 発行 busyでなくなるまで繰り返し */ +u16 SD_SendOpCond(void); /* CMD1 発行 busyでなくなるまで繰り返し */ +u16 SD_SendIfCond(void); /* CMD8 発行 (SDHCのみ反応してくる) */ +u16 SD_SendRelativeAddr(void); /* CMD3 発行 正常終了時 RCA<-ResのRCA */ +u16 SD_SelectCard(void); /* CMD7 発行 Command toggles acard between the Stand-by and Transfer states */ +u16 SD_SetBlockLength(u32 ulBlockLength); /* ブロックレングス(1セクタの転送量)の設定 */ +u16 SD_SendCID(void); /* card identification data の取得コマンド発行 */ +u16 SD_SendCSD(void); /* card-specific data の取得コマンド発行 */ +u16 SD_SendSCR(void); /* SD register の取得コマンド発行 */ +u16 SD_SDStatus(void); /* SD STATUS の取得コマンド発行 */ +u16 SD_SendStatus(void); /* SD status register の取得コマンド発行 */ +u16 SD_MultiReadBlock(u32 ulOffset); /* マルチセクタリードコマンド発行 */ +u16 SD_ClockDivSet(u16 usTranSpeed); /* カードの動作クロック設定 */ + +void SD_EnableClock( void); /* SDカードのクロック有効 */ +void SD_DisableClock( void); /* SDカードのクロック無効(省電力) */ + +u16 SD_SelectBitWidth(s16 b4bit); /* ビット幅の選択 */ + +u16 MMCP_WriteBusWidth(s16 b4bit); +u16 MMCP_BusTest( BOOL readflag); + + +s16 SD_FPGA_irq(void); /* カード転送要求時のFPGAの制御 */ +void SD_StopTransmission(void); /* カード転送終了をFPGAに通知する。 */ +void SD_TransEndFPGA(void); /* カード転送の終了処理(割り込みマスクを戻す) */ +u16 SD_CheckStatus(BOOL bRead); /* Normal response command カードステータスのチェック */ +u16 SD_SwapByte(u16 *data); /* 上位byte、下位byteを入れ替える関数 */ + +void SD_EnableSeccnt( u32 ulSDCARD_SectorCount); /* SD_SECCNTレジスタ有効化&値設定 */ +void SD_DisableSeccnt( void); /* SD_SECCNTレジスタ無効化 */ + +void SD_SetErr(u16 Error); /* エラーステータスを設定する */ +void SD_ClrErr(u16 Error); /* エラーステータスをクリアする */ + +BOOL SD_CheckFPGAReg(u16 reg,u16 value); /* IPレジスタにフラグが立っているか判定 */ + +void SD_TransReadyFPGA(void); /* 転送処理準備FPGA設定 */ +u16 SD_TransCommand(u16 ucCommand); /* 命令発行処理 */ + +u16 SD_MultiWriteBlock(u32 ulOffset); /* マルチセクタライトコマンド発行 */ +u16 SD_SendNumWRSectors(void); /* ACMD22 書きこみ完了セクタ数取得コマンド発行 */ + + +#endif /* __SD_CARD_IP_H__ */ diff --git a/build/libraries/devices/rom_sdmc/ARM7/sdif_reg.h b/build/libraries/devices/rom_sdmc/ARM7/sdif_reg.h new file mode 100644 index 0000000..1d9501b --- /dev/null +++ b/build/libraries/devices/rom_sdmc/ARM7/sdif_reg.h @@ -0,0 +1,118 @@ +/*---------------------------------------------------------------------------* + Project: CTR - SD driver + File: sd_ip_reg.h + + Copyright 2006 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + *---------------------------------------------------------------------------*/ + +#ifndef __SD_IP_REG_H__ +#define __SD_IP_REG_H__ + +/********************************************* + SD IPレジスタ + + (R/W) : readable and writable + (RO) : read only +*********************************************/ +/*#if (CTR_DEF_ENVIRONMENT_DSEMU == 1) +#define SD_IP_BASE (0x08030000) // NTR用ブレッドボード設定 +#else +#define SD_IP_BASE (0x400B0000) // IOP実機設定 +#endif*/ +#define SD_IP_BASE (0x04004800) // TWL ARM7設定 + + +#define SD_CMD (*(vu16 *)(SD_IP_BASE + 0x00)) /* CMD発行レジスタ(R/W) */ +#define SD_PORTSEL (*(vu16 *)(SD_IP_BASE + 0x02)) /* ポート選択レジスタ(R/W) */ +#define SD_ARG0 (*(vu16 *)(SD_IP_BASE + 0x04)) /* Argument[15:0] (R/W) */ +#define SD_ARG1 (*(vu16 *)(SD_IP_BASE + 0x06)) /* Argument[31:16] (R/W) */ +#define SD_STOP (*(vu16 *)(SD_IP_BASE + 0x08)) /* 転送終了後STOP、SD_SECCNT有効 (R/W) */ +#define SD_SECCNT (*(vu16 *)(SD_IP_BASE + 0x0A)) /* 転送セクタ数制御 (R/W) */ +#define SD_RSP0 (*(vu16 *)(SD_IP_BASE + 0x0C)) /* Response [23:8] (RO) */ +#define SD_RSP1 (*(vu16 *)(SD_IP_BASE + 0x0E)) /* Response [39:24] (RO) */ +#define SD_RSP2 (*(vu16 *)(SD_IP_BASE + 0x10)) /* Response [55:40] (RO) */ +#define SD_RSP3 (*(vu16 *)(SD_IP_BASE + 0x12)) /* Response [71:56] (RO) */ +#define SD_RSP4 (*(vu16 *)(SD_IP_BASE + 0x14)) /* Response [87:72] (RO) */ +#define SD_RSP5 (*(vu16 *)(SD_IP_BASE + 0x16)) /* Response [103:88] (RO) */ +#define SD_RSP6 (*(vu16 *)(SD_IP_BASE + 0x18)) /* Response [119:104] (RO) */ +#define SD_RSP7 (*(vu16 *)(SD_IP_BASE + 0x1A)) /* Response [127:120] (RO) */ +#define SD_INFO1 (*(vu16 *)(SD_IP_BASE + 0x1C)) /* SDメモリーカードの状態 (R/W) */ +#define SD_INFO2 (*(vu16 *)(SD_IP_BASE + 0x1E)) /* バッファ制御とエラー情報 (R/W) */ +#define SD_INFO1_MASK (*(vu16 *)(SD_IP_BASE + 0x20)) /* SD_INFO1割込みマスク (R/W) */ +#define SD_INFO2_MASK (*(vu16 *)(SD_IP_BASE + 0x22)) /* SD_INFO2割込みマスク (R/W) */ +#define SD_CLK_CTRL (*(vu16 *)(SD_IP_BASE + 0x24)) /* SDクロック設定 (R/W) */ +#define SD_SIZE (*(vu16 *)(SD_IP_BASE + 0x26)) /* ビット幅と転送データ長の設定 (R/W) */ +#define SD_OPTION (*(vu16 *)(SD_IP_BASE + 0x28)) /* タイムアウト、width、CD検出タイム (R/W) */ +#define SD_ERR_STS1 (*(vu16 *)(SD_IP_BASE + 0x2C)) /* CMD, CRC, ENDエラー割込み原因 (RO) */ +#define SD_ERR_STS2 (*(vu16 *)(SD_IP_BASE + 0x2E)) /* タイムアウトエラー割込み原因 (RO) */ +#define SD_BUF0 (vu16 *)(SD_IP_BASE + 0x30) /* SDバッファ読込/書込データポート (R/W) */ +#define CC_EXT_MODE (*(vu16 *)(SD_IP_BASE + 0xD8)) /* DMAモード/PIOモード切り替え */ +#define SOFT_RST (*(vu16 *)(SD_IP_BASE + 0xE0)) /* ソフトウェアリセット (R/W) */ +#define VERSION (*(vu16 *)(SD_IP_BASE + 0xE2)) /* Version レジスタ (RO) */ +#define EXT_WP (*(vu16 *)(SD_IP_BASE + 0xF6)) /* 拡張SD Card ライトプロテクト (RO) */ +#define EXT_CD (*(vu16 *)(SD_IP_BASE + 0xF8)) /* 拡張SD Card 検出、挿入、抜け フラグ (R/W) */ +#define EXT_CD_DAT3 (*(vu16 *)(SD_IP_BASE + 0xFA)) /* 拡張SD Card 検出、挿入、抜け フラグ (R/W) */ +#define EXT_CD_MASK (*(vu16 *)(SD_IP_BASE + 0xFC)) /* 拡張SD Card 検出、挿入、抜け 割込みマスク (R/W) */ +#define EXT_CD_DAT3_MASK (*(vu16 *)(SD_IP_BASE + 0xFE)) /* 拡張SD Card 検出、挿入、抜け 割込みマスク (R/W) */ + + + +/********************************************* + SD I/F(ラッパー)レジスタ +*********************************************/ +/*#if (CTR_DEF_ENVIRONMENT_DSEMU == 1) +#define SD_IF_BASE (0x08030100) // NTR用ブレッドボード設定 +#else +#define SD_IF_BASE (0x400B0100) // IOP実機設定 +#endif*/ +#define SD_IF_BASE (0x04004900) // IOP実機設定 + + +#define SDIF_CNT ((vu32 *)(SD_IF_BASE+0x00)) /* コントロール */ +#define SDIF_FDS ((vu32 *)(SD_IF_BASE+0x04)) /* FIFOサイズ */ +#define SDIF_FSC ((vu32 *)(SD_IF_BASE+0x08)) /* セクタカウント */ +#define SDIF_FI ((vu32 *)(SD_IF_BASE+0x0c)) /* FIFOウィンドウ */ + +#define SDIF_CNT_L ((vu16 *)(SD_IF_BASE+0x00)) +#define SDIF_CNT_H ((vu16 *)(SD_IF_BASE+0x02)) +#define SDIF_FDS_L ((vu16 *)(SD_IF_BASE+0x04)) +#define SDIF_FDS_H ((vu16 *)(SD_IF_BASE+0x06)) +#define SDIF_FSC_L ((vu16 *)(SD_IF_BASE+0x08)) +#define SDIF_FSC_H ((vu16 *)(SD_IF_BASE+0x0a)) +#define SDIF_FI_L ((vu16 *)(SD_IF_BASE+0x0c)) +#define SDIF_FI_H ((vu16 *)(SD_IF_BASE+0x0e)) + + + +/********************************************* + INTCレジスタ +*********************************************/ +/*#if (CTR_DEF_ENVIRONMENT_DSEMU == 1) +#define CTR_INT_BASE (0x08000000) +#else +#define CTR_INT_BASE (0x40010000) +#endif + + +#define CTR_INT_SE (CTR_INT_BASE + 0x00) //割り込み要求選択レジスタ +#define CTR_INT_IE (CTR_INT_BASE + 0x04) //IE +#define CTR_INT_IF (CTR_INT_BASE + 0x08) //IF + +#define CTR_IE_SD_MASK (1<<13) //SD割り込みフラグ +*/ +#define CTR_INT_BASE (0x04000000) + +#define CTR_INT_SE (CTR_INT_BASE + 0x208) //割り込み要求選択レジスタ +#define CTR_INT_IE (CTR_INT_BASE + 0x218) //IE +#define CTR_INT_IF (CTR_INT_BASE + 0x21C) //IF + +#define CTR_IE_SD_MASK (1<<8) //SD割り込みフラグ + + +#endif /* __SD_IP_REG_H__ */ diff --git a/build/libraries/devices/rom_sdmc/ARM7/sdmc.c b/build/libraries/devices/rom_sdmc/ARM7/sdmc.c new file mode 100644 index 0000000..a9815c6 --- /dev/null +++ b/build/libraries/devices/rom_sdmc/ARM7/sdmc.c @@ -0,0 +1,2529 @@ +/* + Project: CTR SD port driver + File: Carddrv.c + + 2006, Research and Development Department, Nintendo. +*/ + +#include +//#include +#include "sdmc_config.h" +#include "sdif_reg.h" /* IP 対応レジスタ定義 */ +#include "sdmc.h" +#include "sdif_ip.h" /* IP 対応フラグ定義 */ + +/*#if (SD_DEBUG_PRINT_ON == 1) + #if (CTR_DEF_ENVIRONMENT_DSEMU == 1) + #define PRINTDEBUG osTPrintf + #else + #include + #define PRINTDEBUG vlink_dos_printf + #endif +#else + #define PRINTDEBUG( ...) ((void)0) +#endif*/ +// #define PRINTDEBUG OS_TPrintf + #define PRINTDEBUG( ...) ((void)0) + + +/*********************************************************************** + 定数 +***********************************************************************/ +#define SD_STACK_SIZE (4096*2) +//#define SD_THREAD_PRIO (10) +//#define SD_INTR_THREAD_PRIO (SD_THREAD_PRIO - 1) + +#define SD_OPERATION_INIT (0) +#define SD_OPERATION_READ (1) +#define SD_OPERATION_READ_WITH_FIFO (2) +#define SD_OPERATION_WRITE (3) +#define SD_OPERATION_WRITE_WITH_FIFO (4) + + +/*********************************************************************** + extern変数 +***********************************************************************/ +extern u16 BgBak[32*32]; +//u16 sdcard_request_flag; //カードからのデータ転送要求の有無フラグ +static BOOL thread_flag; + + +/*********************************************************************** + global変数 +***********************************************************************/ +BOOL sdmc_tsk_created = FALSE; + +OSThread sdmc_tsk; +OSMessageQueue sdmc_dtq; +OSMessage sdmc_dtq_array[1]; +OSMessageQueue sdmc_result_dtq; +OSMessage sdmc_result_dtq_array[1]; +OSAlarm sdmc_alm; +OSThread sdmc_intr_tsk; +OSThreadQueue sdmc_tsk_q; + + +u64 sd_stack[SD_STACK_SIZE / sizeof(u64)]; +u64 sd_intr_stack[SD_STACK_SIZE / sizeof(u64)]; + +/* drsdmc.cでも参照 */ +SdmcSpec sdmc_current_spec; //TODO:ポート切り替え時、Port0とPort1に保存するように + +typedef struct { //OSMessage + void* buf; + u32 bufsize; + u32 offset; + void (*func)(void); + SdmcResultInfo* info; + u32 operation; + void (*func2)(void); +} SDCARDMsg; + + +/*********************************************************************** + static関数の宣言 +***********************************************************************/ +static void SDCARD_Backup_port0(void); +static void SDCARD_Backup_port1(void); +static void SDCARD_Restore_port0(void); +static void SDCARD_Restore_port1(void); + +static SDMC_ERR_CODE SDCARDi_ReadFifo(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info); +static SDMC_ERR_CODE SDCARDi_WriteFifo(void* buf,u32 bufsize,u32 offset,void(*func)(),SdmcResultInfo *info); + +static SDMC_ERR_CODE SDCARDi_Read(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info); +static SDMC_ERR_CODE SDCARDi_Write(void* buf,u32 bufsize,u32 offset,void(*func)(),SdmcResultInfo *info); + +int MMCP_SetBusWidth( BOOL b4bit); /* ビット幅の選択(MMCplus, eMMC, moviNAND) */ + +SDMC_ERR_CODE SDCARD_Thread( SDCARDMsg* SdMsg); //SDスレッド +static void SDCARD_Intr_Thread( void* arg); //SD割り込み処理スレッド + +SDMC_ERR_CODE sdmcGoIdle( void (*func1)(),void (*func2)()); +/*static*/ SDMC_ERR_CODE i_sdmcInit( void); +/*static*/ SDMC_ERR_CODE SDCARD_Layer_Init(void); +/*static*/ SDMC_ERR_CODE i_sdmcMPInit( void); /* カードドライバ初期化(マルチポート対応) */ + +static u16 i_sdmcErrProcess(void); /* エラー時の処理 */ +static u16 i_sdmcGetResid(u32 *pResid); /* 書きこみ完了セクタ数の取得 */ +static u16 i_sdmcCheckWP(void); /* SDCARD ライトプロテクトチェック */ + +static void i_sdmcEnable( void); /* SD使用のためのOS準備 */ +static void i_sdmcDisable( void); + +static u16 i_sdmcSendSCR(void); /* SCRの読み出し */ +static u16 SDCARD_SD_Status(void); /* SD_STATUSの取得 */ +static u32 SDCARD_GetR1Status(void); /* Normal response command カードステータスを取得 */ + +static void SDCARD_Dmy_Handler( void); /* 何もしない */ +static void SDCARD_Timer_irq(void* arg); /* タイムアウト割り込みハンドラ */ +static void SDCARD_irq_Handler( void); /* SD-IPからの割り込みハンドラ */ +static void SDCARD_FPGA_irq(void); /* カードリードライト割り込み処理 */ +static void SDCARD_ATC0_irq(void); /* ATC0転送完了割り込み処理 */ +static void SYSFPGA_irq(void); /* SYSFPGAエラー割り込み処理 */ + +/*ポート1は無線固定なのでポート選択関数は公開しない*/ +static u16 i_sdmcSelectedNo(void); /* カードポートの選択 */ +static u16 i_sdmcSelect(u16 select); /* 現在のカードポート番号のチェック */ + + + + +/*********************************************************************** + 外部参照変数 +***********************************************************************/ +static void SDCARD_TimerStart(u32 tim); /* タイムアウト計測スタート */ +static void SDCARD_TimerStop(void); /* タイムアウト計測停止 */ + +extern u16 SD_CID[8]; /* CID値保存用 */ +extern u16 SD_CSD[8]; /* CSD値保存用 */ +extern u16 SD_OCR[2]; /* OCR値保存用 */ +extern u16 SD_SCR[4]; /* SCR値保存用 */ +extern u16 SD_RCA; /* RCA値保存用 */ + +extern s16 SDCARD_MMCFlag; /* MMCカードフラグ */ +extern s16 SDCARD_SDHCFlag; /* SDHCカードフラグ */ +extern u16 SD_port_number; /* 現在ポート番号 */ + +//static BOOL init_io_exist; /* SDIO存在フラグ */ +//static BOOL init_mem_exist; /* メモリ存在フラグ */ + + +/*********************************************************************** + グローバル +***********************************************************************/ +u16 SD_SDSTATUS[32]; /* SD_STATUSレジスタ保存用 */ +u16 SDCARD_WP_FLAG0; /* カードライトプロテクトフラグ。0=なし、1=有り */ +u16 SDCARD_WP_FLAG1; /* カードライトプロテクトフラグ。0=なし、1=有り */ +u16 SDCARD_WP_PERMANENT; /* カードライトプロテクト永久フラグ。0=なし、1=有り */ +u16 SDCARD_WP_TEMPORARY; /* カードライトプロテクト一時フラグ。0=なし、1=有り */ + +u16* pSDCARD_BufferAddr; /* 保存用データ格納バッファアドレス */ + +u32 ulSDCARD_SectorCount; /* 転送セクタ数 */ +u32 ulSDCARD_RestSectorCount; /* 残り転送セクタ数 */ +u32 SDCARD_SectorSize; /* セクタサイズ デフォルト 512bytes */ + +u16 SD_INFO1_VALUE; /* SD_INFO1レジスタ取得用変数 */ +u16 SD_INFO1_MASK_VALUE; /* SD_INFO1割込みマスク用変数(0で許可, 1で禁止) */ +u16 SD_INFO2_VALUE; /* SD_INFO2レジスタ取得用変数 */ +u16 SD_INFO2_MASK_VALUE; /* SD_INFO2割り込みマスク用変数(0で許可, 1で禁止) */ +u16 SD_INFO_ERROR_VALUE; /* SD_INFO2, SD_INFO1のエラービット確認用変数 */ + +u16 SD_port_en_numbers; /* サポートするポート数 */ + + +/*--- ポート0 保存変数 ---*/ +u16 SD_CLK_CTRL_port0; +u16 SD_OPTION_port0; + +SDMC_ERR_CODE SDCARD_ErrStatus_port0; +u16 SD_RCA0; +s16 SDCARD_MMCFlag_port0; +u32 SDCARD_Status_port0; +s16 SDCARD_SDFlag_port0; +s16 SDCARD_OutFlag_port0; +SdmcResultInfo *pSDCARD_info_port0; +u16 SDCARD_WP_PERMANENT_port0; +u16 SDCARD_WP_TEMPORARY_port0; +u16 SD_CID_port0[8] = {0}; +u16 SD_CSD_port0[8] = {0}; +/*------------------------*/ + +/*--- ポート1 保存変数 ---*/ +u16 SD_CLK_CTRL_port1; +u16 SD_OPTION_port1; + +SDMC_ERR_CODE SDCARD_ErrStatus_port1; +u16 SD_RCA1; +s16 SDCARD_MMCFlag_port1; +u32 SDCARD_Status_port1; +s16 SDCARD_SDFlag_port1; +s16 SDCARD_OutFlag_port1; +SdmcResultInfo *pSDCARD_info_port1; +u16 SDCARD_WP_PERMANENT_port1; +u16 SDCARD_WP_TEMPORARY_port1; +u16 SD_CID_port1[8] = {0}; +u16 SD_CSD_port1[8] = {0}; +/*------------------------*/ + +u16 TransCount; /* R/W転送カウント変数 */ + +u32 ulSDCARD_Size; /* カード全セクタ数 */ + +volatile s16 SDCARD_ATC0_Flag; /* 全ATC完了フラグ */ +volatile s16 SDCARD_FPGA_Flag; /* FPGA処理完了フラグ */ +volatile s16 SDCARD_EndFlag; /* 転送処理完了フラグ */ + +SDMC_ERR_CODE SDCARD_ErrStatus; /* エラーステータス */ +vu32 SDCARD_Status; /* カードステータス */ +s16 SDCARD_SDFlag; /* SDカードフラグ */ + +volatile s16 SDCARD_OutFlag; /* カード排出発生判定フラグ */ +SdmcResultInfo *pSDCARD_info; /* 保存用実行結果構造体ポインタ */ + +u16 SDCARD_IO_Port; /* カード挿入/排出割り込み発生時のポート番号 */ + +void (*func_SDCARD_In)(void); /* カード挿入イベント用コールバック保存用 */ +void (*func_SDCARD_Out)(void); /* カード排出イベント用コールバック保存用 */ +/* void (*func_SDCARD_CallBack)(SdmcResultInfo *info); 処理結果通知用コールバック保存用 */ + + +/*---------------------------------------------------------------------------* + Name: SDCARD_Backup_port0 + + Description: backup registers and variables of port0. + ポート0のレジスタや変数をバックアップする + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void SDCARD_Backup_port0(void) +{ + /* registers */ + SD_GetFPGA(SD_CLK_CTRL_port0,SD_CLK_CTRL); + SD_GetFPGA(SD_OPTION_port0,SD_OPTION); + + /* variables */ + SDCARD_ErrStatus_port0 = SDCARD_ErrStatus; + SD_RCA0 = SD_RCA; + SDCARD_MMCFlag_port0 = SDCARD_MMCFlag; + SDCARD_Status_port0 = SDCARD_Status; + SDCARD_SDFlag_port0 = SDCARD_SDFlag; + SDCARD_OutFlag_port0 = SDCARD_OutFlag; + pSDCARD_info_port0 = pSDCARD_info; + SDCARD_WP_PERMANENT_port0 = SDCARD_WP_PERMANENT; + SDCARD_WP_TEMPORARY_port0 = SDCARD_WP_TEMPORARY; + + /*registers*/ +#if (TARGET_OS_CTR == 1) + miCpuCopy8( SD_CID, SD_CID_port0, 16); + miCpuCopy8( SD_CSD, SD_CSD_port0, 16); +#else + MI_CpuCopy8( SD_CID, SD_CID_port0, 16); + MI_CpuCopy8( SD_CSD, SD_CSD_port0, 16); +#endif +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_Backup_port1 + + Description: backup registers and variables of port1. + ポート1のレジスタや変数をバックアップする + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void SDCARD_Backup_port1(void) +{ + /* registers */ + SD_GetFPGA(SD_CLK_CTRL_port1,SD_CLK_CTRL); + SD_GetFPGA(SD_OPTION_port1,SD_OPTION); + + /* variables */ + SDCARD_ErrStatus_port1 = SDCARD_ErrStatus; + SD_RCA1 = SD_RCA; + SDCARD_MMCFlag_port1 = SDCARD_MMCFlag; + SDCARD_Status_port1 = SDCARD_Status; + SDCARD_SDFlag_port1 = SDCARD_SDFlag; + SDCARD_OutFlag_port1 = SDCARD_OutFlag; + pSDCARD_info_port1 = pSDCARD_info; + SDCARD_WP_PERMANENT_port1 = SDCARD_WP_PERMANENT; + SDCARD_WP_TEMPORARY_port1 = SDCARD_WP_TEMPORARY; + + /*registers*/ +#if (TARGET_OS_CTR == 1) + miCpuCopy8( SD_CID, SD_CID_port1, 16); + miCpuCopy8( SD_CSD, SD_CSD_port1, 16); +#else + MI_CpuCopy8( SD_CID, SD_CID_port1, 16); + MI_CpuCopy8( SD_CSD, SD_CSD_port1, 16); +#endif +} + + +/*---------------------------------------------------------------------------* + Name: i_sdmcEnable + + Description: assign OS resouce for using SD memory card. + SDカードを使うための準備をする + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void i_sdmcEnable( void) +{ +#if (TARGET_OS_CTR == 1) +#if (CTR_DEF_ENVIRONMENT_DSEMU == 1) + u16 ctrdg_reg; + + ctrdg_reg = (*(vu16*)REG_EXMEMCNT_ADDR) & (0xFF00); /* ブレッドボード設定 */ + *(vu16*)REG_EXMEMCNT_ADDR = (ctrdg_reg | 0); //ARM9優先、PHIにLo出力、1st:10,2nd:6サイクル +#endif + + /*SD interrupt setting*/ +// osInitIntrFlag(); +// osClearInterruptPendingID( OS_INTR_ID_SD); +// *(vu32*)CTR_INT_IF = CTR_IE_SD_MASK; + osSetInterruptHandler( OS_INTR_ID_SD, SDCARD_irq_Handler); + osEnableInterruptID( OS_INTR_ID_SD); +// *(vu32*)CTR_INT_SE = CTR_IE_SD_MASK; //割り込み(IRQ)発生許可 +// *(vu32*)CTR_INT_IE = CTR_IE_SD_MASK; +// osEnableInterrupts(); +// *(vu16*)0x04000208 = 1; +#else + /*SD割り込みのIF解除*/ + *(vu16*)CTR_INT_IF = CTR_IE_SD_MASK; + OS_SetIrqFunction( OS_IE_SD, SDCARD_irq_Handler); + OS_EnableIrqMask( OS_IE_SD); +#endif +} + +/*---------------------------------------------------------------------------* + Name: i_sdmcDisable + + Description: under construction + 工事中 + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void i_sdmcDisable( void) +{ +} + + +/*---------------------------------------------------------------------------* + Name: SDCARD_irq_Handler + + Description: SD interrupt handler + SD割り込みハンドラ + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void SDCARD_irq_Handler( void) +{ +#if (TARGET_OS_CTR == 1) + iwup_tsk( sdmc_intr_tsk_id); +#else + PRINTDEBUG( "SD irq!\n"); + OS_SetIrqCheckFlag( OS_IE_SD); + SDCARD_Intr_Thread( NULL); +//TODO! OS_WakeupThreadDirect( &sdmc_intr_tsk); +#endif +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_Dmy_Handler + + Description: dmy handler for timer interrupt. + タイマー割り込み用ダミーハンドラ + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void SDCARD_Dmy_Handler( void) +{ +} + +/*---------------------------------------------------------------------------* + Name: sdmcInit + + Description: Initialize SD interface and SD card. + 初期化 + + Arguments: func1 : カード挿入時コールバック関数 + func2 : カード排出時コールバック関数 + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcInit(void (*func1)(),void (*func2)()) +{ +// SDCARDMsg SdMsg; +// u32 init_msg; + SDMC_ERR_CODE api_result; + + if( sdmc_tsk_created == FALSE) { + /*---------- OS準備 ----------*/ + if( !OS_IsAlarmAvailable()) { /* アラームチェック(OS_InitAlarm済みか?) */ + SDCARD_ErrStatus |= SDMC_ERR_END; + }else{ + OS_CreateAlarm( &sdmc_alm); //使用可能であれば初期化 + } + + /* メッセージ初期化 */ +// OS_InitMessageQueue( &sdmc_dtq, &sdmc_dtq_array[0], 1); +// OS_InitMessageQueue( &sdmc_result_dtq, &sdmc_result_dtq_array[0], 1); + +// OS_InitThread(); //自分の優先度が16になる + + /*----------------------------*/ + /**/ + sdmc_tsk_created = TRUE; + } + + /**/ + func_SDCARD_In = func1; /* カード挿入イベント用関数のアドレスを設定 */ + func_SDCARD_Out = func2; /* カード排出イベント用関数のアドレスを設定 */ + api_result = sdmcGoIdle( func1, func2); +// api_result = SDMC_NORMAL; + + return api_result; +} + +/* カードが入れ換わったときなどに初期化(RTFS用)*/ +SDMC_ERR_CODE sdmcGoIdle( void (*func1)(),void (*func2)()) +{ + SDCARDMsg SdMsg; +// OSMessage init_msg; + SDMC_ERR_CODE api_result; + + func_SDCARD_In = func1; /* カード挿入イベント用関数のアドレスを設定 */ + func_SDCARD_Out = func2; /* カード排出イベント用関数のアドレスを設定 */ + + /*----- SDスレッドと通信 -----*/ + SdMsg.operation = SD_OPERATION_INIT; +// SdMsg.func = func1; +// SdMsg.func2 = func2; + +// init_msg = (OSMessage)&SdMsg; + api_result = SDCARD_Thread( &SdMsg); +// OS_SendMessage( &sdmc_dtq, init_msg, OS_MESSAGE_BLOCK); + + /* 返り値待ち */ +// OS_ReceiveMessage( &sdmc_result_dtq, &init_msg, OS_MESSAGE_BLOCK); +// api_result = *(SDMC_ERR_CODE*)init_msg; + /*----------------------------------*/ + + return api_result; +} + + +/*---------------------------------------------------------------------------* + Name: i_sdmcInit + + Description: Initialize SD interface and SD card. + 初期化 + + Arguments: + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +/*static*/ SDMC_ERR_CODE i_sdmcInit( void) +{ + i_sdmcEnable(); + + /* SD初期化 */ + SDCARD_ErrStatus = sdmcReset(); + + if(!SDCARD_ErrStatus) { + SDCARD_ErrStatus = i_sdmcMPInit(); + } + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: sdmcReset + + Description: reset SD card. + リセット + + Arguments: + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcReset( void) +{ + OSIntrMode irq_core_flag; + ulSDCARD_Size = 0; /* カード全セクタ数クリア */ + SDCARD_MMCFlag = FALSE; /* MMCカード判定フラグクリア */ + SDCARD_SDHCFlag = FALSE; + SDCARD_SDFlag = FALSE; /* SDカード判定フラグクリア */ + + /*** カードステータスをクリア ***/ + SDCARD_ErrStatus = SDMC_NORMAL; + SDCARD_Status = SDMC_NORMAL; + + /*** カードCSD WPビットをクリア ***/ + SDCARD_WP_FLAG0 = 0; + SDCARD_WP_FLAG1 = 0; + SDCARD_WP_PERMANENT = 0; + SDCARD_WP_TEMPORARY = 0; + + pSDCARD_info = NULL; + SDCARD_OutFlag = FALSE; /* カード排出発生判定フラグクリア */ + +#if (TARGET_OS_CTR == 1) + irq_core_flag = osDisableInterrupts(); /* 割込み禁止 */ +#else + irq_core_flag = OS_DisableInterrupts(); /* 割込み禁止 */ +#endif + *SDIF_CNT_L = 0x0402; //ラッパーレジスタ + *SDIF_CNT_L = 0x0000; //ラッパーレジスタ + *SDIF_FDS_L = 0; + *SDIF_FSC_L = 1; + SD_Init(); /* SD Card I/F 初期化処理 */ + SD_AndFPGA( SD_OPTION, SD_CD_DETECT_TIME); /* CD 検出タイムをゼロクリア */ + + SD_port_en_numbers = SDCARD_PORT_NO_MAX; /*** サポートするポート数をデフォルトに設定 ***/ + SD_port_number = 0; /*** 現在のポート番号をデフォルトに設定 ***/ + + SDCARD_Backup_port0(); /* port0 backup */ + SDCARD_Backup_port1(); /* port1 backup */ + +#if (TARGET_OS_CTR == 1) + osRestoreInterrupts( irq_core_flag); /* 割り込み設定を元に戻す */ +#else + OS_RestoreInterrupts( irq_core_flag); /* 割り込み設定を元に戻す */ +#endif + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_Layer_Init + + Description: initialize sequence for SD card. + SDカード規定の初期化手順 + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +/*static*/ SDMC_ERR_CODE SDCARD_Layer_Init(void) +{ + u32 ulCSize; +// SYSTIM wait_tim, limit_tim; + u16 read_block_len_val, mult_val; + +// u16 memory_exist, function_number; + SDCARD_Status = SDMC_NORMAL; /* カードステータスをクリア */ +/* func_SDCARD_CallBack = NULL; */ + pSDCARD_info = NULL; + SDCARD_EndFlag = TRUE; /* 転送処理完了フラグセット */ + SDCARD_MMCFlag = FALSE; /* MMCカード判定フラグクリア */ + SDCARD_SDHCFlag = FALSE; + SDCARD_SDFlag = FALSE; /* SDカード判定フラグクリア */ + SDCARD_OutFlag = FALSE; /* カード排出発生判定フラグクリア */ + ulSDCARD_Size = 0; /* カード全セクタ数クリア */ + TransCount = 0; /* 転送カウント変数クリア */ +// init_io_exist = 0; +// init_mem_exist = 0; + + SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_256)); /* SDクロックの周波数 144KHz */ + SD_EnableClock(); /* SDカードのクロックをイネーブルにする */ + + /* SD I/F部ダミー80クロック(1mSec)転送待ち(タイマーで待ちを実装しても良い) */ +#if (TARGET_OS_CTR == 1) + dly_tsk( 1); +#else +// OS_Sleep( 1); + SVC_WaitByLoop( 17900); //179*4サイクル=716サイクル=10024ns=10us +#endif + + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスをクリア */ + + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RESET_TIMEOUT); /* タイムアウト判定用タイマスタート */ +#endif + + /***********************ここからSDIOテスト*************************/ +// SDIO_RWDirectCommand(); +/* while( 1) { + SDIO_ReadOCR(); + if(SDCARD_ErrStatus){ // エラーステータスの確認(エラー有り?) + init_io_exist = 0; + break; //メモリ初期化へ + } + memory_exist = SD_OCR[1] & SD_OCR_MEMORY_PRESENT; + function_number = (SD_OCR[1] & SD_OCR_NUM_OF_FUNC)>>12; + if( function_number > 0) { // function number が 0でないか? + if( (SD_OCR[0] == 0x0000)&&((SD_OCR[1]&SD_OCR_OCR_23_16)==0x0000)) { //OCR invalidか? + if( memory_exist) { //メモリが存在するか? + init_mem_exist = 1; + break; //メモリカード初期化へ + }else{ + init_mem_exist = 0; + return SDCARD_ErrStatus; //エラー(OCR invalid & メモリなし) + } + } + SDIO_WriteOCR(); + if(SDCARD_ErrStatus){ // エラーステータスの確認(エラー有り?) + init_io_exist = 0; + return SDCARD_ErrStatus; + } + init_io_exist = 1; + memory_exist = SD_OCR[1] & SD_OCR_MEMORY_PRESENT; + if( memory_exist) { + break; //メモリ初期化へ + }else{ + //IO初期化の続き(CMD3)へ + } + } + } +*/ + /******************************************************************/ + + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RESET_TIMEOUT); /* タイムアウト判定用タイマスタート */ +#endif + + PRINTDEBUG( " CMD0(GO_IDLE_STATE)\n"); + SD_ClrErr((u16)(~SDMC_ERR_FPGA_TIMEOUT)); /* タイムアウト以外のエラーをクリア */ + { +/*PRINTDEBUG( "SD_INFO1 : 0x%x\n", SD_INFO1); +PRINTDEBUG( "SD_INFO2 : 0x%x\n", SD_INFO2); +PRINTDEBUG( "SD_INFO1_MASK : 0x%x\n", SD_INFO1_MASK); +PRINTDEBUG( "SD_INFO2_MASK : 0x%x\n", SD_INFO2_MASK); +PRINTDEBUG( "SD_CLK_CTRL : 0x%x\n", SD_CLK_CTRL); +PRINTDEBUG( "SD_SIZE : 0x%x\n", SD_SIZE); + +PRINTDEBUG( "SD_INFO1_MASK : 0x%x\n", (*(vu32 *)(SD_IP_BASE + 0x20)));*/ + } + SD_Command(SD_CMD_CMD | GO_IDLE_STATE); /* CMD0発行、レスポンス確認 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + + /*------- idle state -------*/ +#if (TARGET_OS_CTR == 1) + dly_tsk( 1); /* 1ms待ち */ +#else +// OS_Sleep( 1); + SVC_WaitByLoop( 17900); //179*4サイクル=716サイクル=10024ns=10us +#endif + SD_SendIfCond(); /* CMD8発行、レスポンス確認 */ + if( !SDCARD_SDHCFlag) { /* SDHC以外は失敗してるはずなので */ + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーフラグをクリアしておく */ + } + + while(!(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT)){ /* タイムアウトになったら抜ける */ + SD_ClrErr((u16)(~SDMC_ERR_FPGA_TIMEOUT)); + + SD_RCA = 0; /* RCA = 0をセット */ + if(!SDCARD_MMCFlag){ /* MMCカードフラグが 0(OFF) か? */ + if(!SD_AppCommand()){ /* CMD55 発行処理が正常か? */ + SDCARD_MMCFlag = FALSE; /* MMCカードフラグクリア */ + if(!SD_AppOpCond()){ /* ACMD41発行処理が正常か?(OCR31bit = L の時 No Response) */ + SDCARD_SDFlag = TRUE; /* SDカードフラグセット */ + break; + } + }else{ /* CMD55 が正常終了しない */ + if(SDCARD_ErrStatus == SDMC_ERR_TIMEOUT){ /* タイムアウト(==No Response)か? */ + SDCARD_MMCFlag = TRUE; /* MMCカードフラグセット */ + }else{ +// break; //コメントアウトしないとSDカードの初期化に失敗する + } + } + } + if(SDCARD_MMCFlag){ /* MMCカードフラグが 1(ON) のとき */ + SD_RCA = 1; /* RCA = 1をセット */ + if(!SD_SendOpCond()){ /* CMD1発行処理が正常か? */ + break; + } + } + } +/* + if( SDCARD_SDHCFlag) { + SD_ReadOCR(); + } +*/ + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?)*/ + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーかチェック */ + SD_ClrErr(SDMC_ERR_FPGA_TIMEOUT); /* タイムアウトエラーの設定クリア */ + SD_SetErr(SDMC_ERR_RESET); /* 初期化カードリセットコマンド時1.5秒タイムアウトエラーの設定 */ + } + SDCARD_MMCFlag = FALSE; /* MMCカードフラグクリア */ + return SDCARD_ErrStatus; + } + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_INITIAL_TIMEOUT); /* タイムアウト判定用タイマスタート */ +#endif +PRINTDEBUG( "%d\n", __LINE__); + + SD_SendCID(); /* CMD2発行 レスポンス確認 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + + while(1){ + SD_SendRelativeAddr(); /* CMD3発行 レスポンス確認 正常終了時 RCA<-ResのRCA */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + if(SD_RCA != 0){ + break; + } + } + + /*------- standby state -------*/ +PRINTDEBUG( "%d\n", __LINE__); + SD_SendCSD(); /* CMD9発行 レスポンス確認 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + SDCARD_WP_PERMANENT = (u16)(SD_CSD[0] & (u16)(SDCARD_WP_PERMANENT_BIT)); + SDCARD_WP_TEMPORARY = (u16)(SD_CSD[0] & (u16)(SDCARD_WP_TEMPORARY_BIT)); + + /* 転送速度設定 */ + SD_ClockDivSet(SD_RSP5); /* SDカードの動作クロック設定 (CSD[5]) */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + + /* Command toggles acard between the Stand-by and Transfer states */ + SD_SelectCard(); /* CMD7発行 レスポンス確認 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + + /*------- translate state -------*/ + + SDCARD_SectorSize = SECTOR_SIZE; /* セクタサイズ デフォルト 512bytes */ + SD_SetBlockLength(SDCARD_SectorSize); /* CMD16 ブロックサイズの設定 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + +#if SCR + SD_SelectBitWidth(FALSE); /* CMD55->ACMD6 ビット幅の選択 1bit */ +PRINTDEBUG( "%d\n", __LINE__); + + /* ACMD51 発行 SD configuration register (SCR) */ + if(SDCARD_SDFlag){ /* SDカードフラグ ON かチェック */ + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + i_sdmcSendSCR(); + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } +#if TIMEOUT + SDCARD_TimerStart(SDCARD_CLOCK_WAIT);/* タイムアウト判定用タイマスタート */ +#endif + } +#endif + SD_EnableClock(); /* SD-CLK Enable */ + + if(SDCARD_MMCFlag){ /* MMCカード ON かチェック */ + if( ((SD_CSD[7] & 0x3C)>>2) >= 4) { + MMCP_SetBusWidth( TRUE); + } +// SD_SelectBitWidth(FALSE); /* CMD55->ACMD6 ビット幅の選択 1bit */ + }else{ + SD_SelectBitWidth(TRUE); /* CMD55->ACMD6 ビット幅の選択 4bit */ + } + + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + + if(SDCARD_SDFlag){ /* SDカードフラグ ON かチェック */ + if (SDCARD_SD_Status()) /* CMD55->ACMD13 カードステータスを取得 */ + return SDCARD_ErrStatus; + if(SD_SDSTATUS[1] & SD_MEMORY_CARD){ + SDCARD_SDFlag = FALSE; /* SDカードフラグクリア */ + } + } + + /*--------------カードサイズの算出---------------*/ + if( ((SD_CSD[7] & CSD_STRUCT_BIT_127_126) >> 6) == 0x1) { //SDHCのとき + sdmc_current_spec.csd_ver2_flag = 1; + ulCSize = (u32)((((u32)(SD_CSD[3]) & CSD_C_SIZE_BIT_69_56) << 8) + + ((SD_CSD[2] & CSD_C_SIZE_BIT_55_48) >> 8) + 1); + ulCSize = ulCSize * 1024; //もともと512KByte単位なのを512Byte単位にする + /* データ領域サイズ算出 */ + sdmc_current_spec.memory_capacity = ulCSize; + ulSDCARD_Size = ulCSize; + /* プロテクト領域サイズ算出 */ + sdmc_current_spec.protected_capacity = (((SD_SwapByte( &SD_SDSTATUS[2])) << 16) + + (SD_SwapByte( &SD_SDSTATUS[3]))) / 0x200; + /*トータルサイズ算出 */ + sdmc_current_spec.card_capacity = sdmc_current_spec.memory_capacity + + sdmc_current_spec.protected_capacity; + + }else{ //従来SDカードのとき + sdmc_current_spec.csd_ver2_flag = 0; + ulCSize = (u32)(((SD_CSD[3] & CSD_C_SIZE_BIT_71_62) >> 6) + + ((SD_CSD[4] & CSD_C_SIZE_BIT_73_72) << 10) + 1); + mult_val = ((SD_CSD[2] & CSD_C_SIZE_MULT) >> 7) + 2; //2の乗数 + ulCSize = ulCSize << mult_val; + if(SDCARD_MMCFlag){ /* MMCカードフラグON かチェック */ + read_block_len_val = ((SD_CSD[4] & CSD_READ_BL_LEN) >> 8); + ulCSize = (ulCSize << read_block_len_val); + }else{ /* SDカードフラグ(SDCARD_SDFlag)ON のはず */ + read_block_len_val = (((SD_CSD[1] & CSD_WRITE_BL_LEN_BIT_25_24) << 2) | + ((SD_CSD[0] & CSD_WRITE_BL_LEN_BIT_23_22) >> 14)); + ulCSize = (ulCSize << read_block_len_val); + } + /* データ領域サイズ算出 */ + ulCSize /= SDCARD_SectorSize; /* 全セクタ数の算出 */ + sdmc_current_spec.memory_capacity = ulCSize; + ulSDCARD_Size += ulCSize; /* 全セクタ数のセット */ + /* プロテクト領域サイズ算出 */ + sdmc_current_spec.protected_capacity = ((SD_SwapByte( &SD_SDSTATUS[2])) << 16) + + (SD_SwapByte( &SD_SDSTATUS[3])); + sdmc_current_spec.protected_capacity <<= mult_val; + sdmc_current_spec.protected_capacity <<= read_block_len_val; + sdmc_current_spec.protected_capacity /= SDCARD_SectorSize; //TODO:構造体にまとめること + /*トータルサイズ算出 */ + sdmc_current_spec.card_capacity = sdmc_current_spec.memory_capacity + + sdmc_current_spec.protected_capacity; + } + sdmc_current_spec.SS = SDCARD_SectorSize; + + PRINTDEBUG( "SD memory capacity : 0x%x\n", sdmc_current_spec.memory_capacity); + PRINTDEBUG( "SD protected capacity : 0x%x\n", sdmc_current_spec.protected_capacity); + PRINTDEBUG( "SD total capacity : 0x%x\n", sdmc_current_spec.card_capacity); + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: i_sdmcMPInit + + Description: initialize SD card in multi ports. + マルチポートのSDカード初期化 + + Arguments: + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +/*static*/ SDMC_ERR_CODE i_sdmcMPInit( void) +{ + if(((SD_port_number == SDCARD_PORT0) && (!SD_CheckFPGAReg(SD_INFO1,SD_INFO1_DETECT))) || + ((SD_port_number == SDCARD_PORT1) && (!SD_CheckFPGAReg(EXT_CD,EXT_CD_PORT1_DETECT))) || + (SD_port_number > SDCARD_PORT1)) + { + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスをクリア */ + SDCARD_OutFlag = TRUE; /* 排出フラグをセット */ + }else{ + SDCARD_ErrStatus = SDCARD_Layer_Init(); + SDCARD_OutFlag = FALSE; /* 排出フラグをリセット */ + } + + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + SD_DisableClock(); /* SD-CLK Disable */ + SD_EnableInfo(); /* SD Card 挿抜 割り込み許可 */ + + return SDCARD_ErrStatus; +} + + +/*---------------------------------------------------------------------------* + Name: sdmcGetStatus + + Description: get card status + カードの状態を取得する + bit15 SDカード判別ビット(検出したら1) + bit14 MMCカード判別ビット(検出したら1) + bit10 IO3 card detect(検出したら1) ※CTRではプルアップのため使えない + bit9 IO3 card inserted(挿入動作で1) ※CTRではプルアップのため使えない + bit8 IO3 card removed(脱動作で1) ※CTRではプルアップのため使えない + bit7 write protect(書き込み禁止の場合1) + bit5 card detect(検出したら1) + bit4 card inserted(挿入動作で1) + bit3 card removed(脱動作で1) + bit2 R/W access all end + bit0 Response end + + Arguments: *status : カードの状態を格納する変数へのポインタ + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +/*----------------------------------------------- +SD_INFO1レジスタ +bit[10,9,8,7] = DAT3CD, DAT3IN, DAT3OUT, WP +bit[5, 4, 3, 2] = CD, INS, REM, ALLEND +bit0 = RESEND +------------------------------------------------- +EXT_CDレジスタ +bit[2,1,0] = P1CD, P1INS, P1REM +------------------------------------------------- +EXT_CD_DAT3レジスタ +bit[2, 1, 0] = P1DCD, P1DINS, P1DREM +------------------------------------------------- +EXT_WPレジスタ +bit0 = P1WP +-----------------------------------------------*/ +SDMC_ERR_CODE sdmcGetStatus(u16 *status) +{ + u16 SD_INFO1_STATUS; + + SD_INFO1_STATUS = SD_INFO1; /* SD_INFO1レジスタ読み出し */ + *status = SD_INFO1_STATUS; /* 論理反転 */ + + /*--- ポート0のとき ---*/ + if(SD_port_number == SDCARD_PORT0) + { + *status &= SDCARD_FLAG_CLR; /* SD/MMCフラグクリア */ + } + /*--- ポート1のとき ---*/ + else if (SD_port_number == SDCARD_PORT1) + { + *status &= SDCARD_PORT1_CLR; /* port1に関係ない部分をクリア */ + SD_INFO1_STATUS = (u16)((EXT_CD & 0x0007) << 3); + SD_INFO1_STATUS |= ((EXT_CD_DAT3 & 0x0007) << 8); + SD_INFO1_STATUS |= ((EXT_WP & 0x0001) << 7); + *status |= SD_INFO1_STATUS; /* カードport1フラグ設定 */ + } + /*--- SD/MMCフラグをセット ---*/ + if( SDCARD_MMCFlag) { /* 検出したカードがMMCカードの時 */ + *status |= SDCARD_FLAG_MMC; /* カード判定部分MMCカード */ + } + if( SDCARD_SDFlag) { /* 検出したカードがSDカードの時 */ + *status |= SDCARD_FLAG_SD; /* カード判定部分SDカード */ + } + + return SDMC_NORMAL; +} + + +/*---------------------------------------------------------------------------* + Name: SDCARD_GetR1Status + + Description: get the card status of R1 response. + R1レスポンスのカードステータスを取得する。 + + Arguments: None + + Returns: SDCARD_Status : R1の[39:8] + *---------------------------------------------------------------------------*/ +static u32 SDCARD_GetR1Status(void) +{ + /* SD_CheckStatusでSDCARD_Statusに値が入る */ + return SDCARD_Status; +} + + +/*---------------------------------------------------------------------------* + Name: sdmcReadFifo + + Description: read from card. + ラッパーのFIFOを使用してカードからの読み出し。 + + Arguments: buf : 読み出したデータを格納するためのバッファのアドレス + bufsize : 読み出しサイズ(セクタ数) + offset : 読み出し開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcReadFifo(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info) +{ + SDCARDMsg SdMsg; +#if (TARGET_OS_CTR == 1) + u32 recv_dat; +#else +// OSMessage recv_dat; +#endif + SDMC_ERR_CODE api_result; //SDCARD関数の返り値 + + SdMsg.buf = buf; + SdMsg.bufsize = bufsize; + SdMsg.offset = offset; + SdMsg.func = func; + SdMsg.info = info; + SdMsg.operation = SD_OPERATION_READ_WITH_FIFO; + +// recv_dat = (OSMessage)&SdMsg; //SdMsgのアドレスを伝える + api_result = SDCARD_Thread( &SdMsg); +// OS_SendMessage( &sdmc_dtq, recv_dat, OS_MESSAGE_BLOCK); + + /* 返り値待ち */ +// OS_ReceiveMessage( &sdmc_result_dtq, &recv_dat, OS_MESSAGE_BLOCK); +// api_result = (SDMC_ERR_CODE)recv_dat; + + return api_result; +} + +/*---------------------------------------------------------------------------* + Name: SDCARDi_ReadFifo + + Description: read from card. + ラッパーのFIFOを使用してカードからの読み出し。 + + Arguments: buf : 読み出したデータを格納するためのバッファのアドレス + bufsize : 読み出しサイズ(セクタ数) + offset : 読み出し開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE SDCARDi_ReadFifo(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info) +{ + SDMC_ERR_CODE result; + + /* FIFO Empty割り込み無効、FIFO Full割り込み有効 */ + *(SDIF_CNT) = (*(SDIF_CNT) & (~SDIF_CNT_FEIE)) | SDIF_CNT_FFIE; + *(SDIF_FDS) = (u16)SDCARD_SectorSize; /* FIFOのデータサイズ */ + *(SDIF_FSC) = bufsize; + *(SDIF_CNT) |= SDIF_CNT_USEFIFO; /* FIFO使用フラグON */ + CC_EXT_MODE = CC_EXT_MODE_DMA; /* DMAモードON */ + + result = SDCARDi_Read( buf, bufsize, offset, func, info); + + /* FIFO無効に */ + *(SDIF_CNT) &= (~SDIF_CNT_USEFIFO); /* FIFO使用フラグOFF */ + CC_EXT_MODE = CC_EXT_MODE_PIO; /* PIOモード(DMAモードOFF) */ + + return result; +} + +/*---------------------------------------------------------------------------* + Name: sdmcRead + + Description: read from card. + カードからの読み出し。 + + Arguments: buf : 読み出したデータを格納するためのバッファのアドレス + bufsize : 読み出しサイズ(セクタ数) + offset : 読み出し開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcRead(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info) +{ + SDCARDMsg SdMsg; +#if (TARGET_OS_CTR == 1) + u32 recv_dat; +#else + OSMessage recv_dat; +#endif + SDMC_ERR_CODE api_result; + + SdMsg.buf = buf; + SdMsg.bufsize = bufsize; + SdMsg.offset = offset; + SdMsg.func = func; + SdMsg.info = info; + SdMsg.operation = SD_OPERATION_READ; + +// recv_dat = (OSMessage)&SdMsg; + api_result = SDCARD_Thread( &SdMsg); +// OS_SendMessage( &sdmc_dtq, recv_dat, OS_MESSAGE_BLOCK); + + /* 返り値待ち */ +// OS_ReceiveMessage( &sdmc_result_dtq, &recv_dat, OS_MESSAGE_BLOCK); +// api_result = (SDMC_ERR_CODE)recv_dat; + + return api_result; +} + +/*---------------------------------------------------------------------------* + Name: SDCARDi_Read + + Description: read from card. + カードからの読み出し。 + + Arguments: buf : 読み出したデータを格納するためのバッファのアドレス + bufsize : 読み出しサイズ(セクタ数) + offset : 読み出し開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE SDCARDi_Read(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info) +{ + s16 nRetryCount; /* リトライ回数カウント */ + SDMC_ERR_CODE SaveErrStatus; /* エラーステータス保存用 */ + u32 SaveStatus; /* カードステータス保存用 */ + + for( nRetryCount=0; nRetryCountresult = SDCARD_ErrStatus; /* SdmcResultInfo に情報設定 */ + pSDCARD_info->resid = (ulSDCARD_SectorCount - ulSDCARD_RestSectorCount) * + SDCARD_SectorSize; /* SdmcResultInfo に処理セクタ数設定 */ + } + } + } + }else{ /*--- 残りセクタ数が 0 でないとき ---*/ + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RW_TIMEOUT); /* タイムアウト判定用タイマスタート(4000msec) */ +#endif + } +} + +/*---------------------------------------------------------------------------* + Name: SYSFPGA_irq + + Description: insert/remove/error/access end interrupt handler. + BREやBWE割り込みを除く割り込みのハンドラ。挿抜、エラー発生、 + アクセス終了の割り込み発生時にそれぞれの処理を行う。 + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void SYSFPGA_irq(void) +{ + /*--- ポート0の挿抜割り込みチェックとコールバック起動 ---*/ + if(!SD_CheckFPGAReg( SD_INFO1_MASK, SD_INFO1_MASK_REMOVE)){ /* SD Card 抜け 割込み許可状態か? */ + if( SD_CheckFPGAReg( SD_INFO1, SD_INFO1_REMOVE)){ /* SD Card 抜け 発生か? */ + SD_AndFPGA( SD_INFO1,(~SD_INFO1_REMOVE)); /* INFO1の抜けフラグを落とす */ + SDCARD_OutFlag = TRUE; /* 排出フラグセット */ + if(func_SDCARD_Out){ /* コールバック関数のNullチェック */ + SDCARD_IO_Port = SDCARD_PORT0; /* カード抜けポート番号を設定 */ + func_SDCARD_Out(); /* カード抜けコールバック関数呼び出し */ + } + } + } + if(!SD_CheckFPGAReg( SD_INFO1_MASK, SD_INFO1_MASK_INSERT)){ /* SD Card 挿入 割込み許可状態か? */ + if( SD_CheckFPGAReg( SD_INFO1, SD_INFO1_INSERT)){ /* SD Card 挿入 発生か? */ + SD_AndFPGA( SD_INFO1, (~SD_INFO1_INSERT)); /* INFO1の挿入フラグを落とす */ + SDCARD_OutFlag = FALSE; /* 排出フラグリセット */ + if(func_SDCARD_In){ /* コールバック関数のNullチェック */ + SDCARD_IO_Port = SDCARD_PORT0; /* カード挿入ポート番号を設定 */ + func_SDCARD_In(); /* カード挿入コールバック関数呼び出し */ + } + } + } + /* (CTRはポート1のCD端子が未接続(常に挿入状態)なので、ポート1の挿抜チェックは行わない) */ + + /*--- 割り込み要求と割り込みマスクを保存 ---*/ + SD_GetFPGA( SD_INFO1_VALUE, SD_INFO1); + SD_GetFPGA( SD_INFO1_MASK_VALUE, SD_INFO1_MASK); + SD_GetFPGA( SD_INFO2_VALUE, SD_INFO2); + SD_GetFPGA( SD_INFO2_MASK_VALUE, SD_INFO2_MASK); + /*------------------------------------------*/ + + /*--- SD_INFO2のエラーフラグ作成 ---*/ + SD_INFO_ERROR_VALUE = (u16)(SD_INFO2_VALUE & (~SD_INFO2_MASK_VALUE)); + /*--- エラーステータス作成 (RESTIMEOUTとILAエラーのフラグは反映しない) ---*/ + SDCARD_ErrStatus |= SD_INFO_ERROR_VALUE & (~(SD_INFO2_ERR_RESTIMEOUT)) & + (~(SD_INFO2_ERR_ILA)) & SD_INFO2_MASK_ERRSET; + + /*--- RESTIMEOUTとILAエラーはフラグの位置をずらして反映する ---*/ + if( SD_INFO_ERROR_VALUE & SD_INFO2_ERR_ILA) { + SDCARD_ErrStatus |= SDMC_ERR_ILA; /* イリーガルアクセスエラー発生 */ + } + if( SD_INFO_ERROR_VALUE & SD_INFO2_ERR_RESTIMEOUT) { + SDCARD_ErrStatus |= SDMC_ERR_TIMEOUT; /* Response Time out エラー発生 */ + }/*------------------------------------------------------------*/ + + SD_AndFPGA( SD_INFO2,(~(SD_INFO2_ERROR_SET))); /* SD_INFO2のエラーフラグを全て落とす */ + if ( SDCARD_ErrStatus) { /* 何らかのエラーが発生しているか? */ + SD_OrFPGA( SD_INFO2_MASK, SD_INFO2_MASK_ERRSET); /* 全てのエラー割り込みを禁止 */ + } + /*--- SD_INFO2のエラーチェック終了 ---*/ + + + /*--- SD_INFO1の割り込み発生状況フラグ作成 ---*/ + SD_INFO_ERROR_VALUE = (u16)(SD_INFO1_VALUE & (~SD_INFO1_MASK_VALUE)); + + if( SD_INFO_ERROR_VALUE & SD_INFO1_MASK_ALL_END) { /* R/W access all end 割込み発生か? */ + SD_OrFPGA( SD_INFO1_MASK, SD_INFO1_MASK_ALL_END); /* INFO1の access all end 割込み禁止 */ + SDCARD_FPGA_Flag = TRUE; /* R/Wアクセス終了(IP処理完了)フラグセット */ + if( SDCARD_ATC0_Flag) { /* 転送完了処理(SDCARD_ATC0_irq)が完了しているか? */ + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + SD_TransEndFPGA(); /* 転送終了処理(割り込みマスクを禁止に戻す) */ + if( SDCARD_EndFlag == FALSE) { /* 転送が終了していないか? */ + SDCARD_EndFlag = TRUE; /* 転送処理完了フラグセット */ + if( pSDCARD_info) { /* Nullチェック */ + pSDCARD_info->result = SDCARD_ErrStatus; /* SdmcResultInfo に情報設定 */ + pSDCARD_info->resid = (ulSDCARD_SectorCount - ulSDCARD_RestSectorCount) * + SDCARD_SectorSize; /* SdmcResultInfo に処理セクタ数設定 */ + } + } /* 転送が終了済みのとき */ + return; + } /* 全ATC完了フラグ OFF の場合 */ + if( SDCARD_ErrStatus != SDMC_NORMAL) { /* エラーが発生している場合 */ + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + if( SDCARD_EndFlag == FALSE) { /* 転送が終了していないか? */ + SD_TransEndFPGA(); /* カード転送の終了処理 */ + SDCARD_EndFlag = TRUE; /* 転送処理完了フラグセット */ + /* SD_Init(); */ /* SD Cardインターフェース部をリセット&初期設定 */ + if( pSDCARD_info) { /* Nullチェック */ + pSDCARD_info->result = SDCARD_ErrStatus; /* SdmcResultInfo に情報設定 */ + pSDCARD_info->resid = (ulSDCARD_SectorCount - ulSDCARD_RestSectorCount) * + SDCARD_SectorSize; /* SdmcResultInfo に処理セクタ数設定 */ + } + } + } + } /* R/W access all end 割り込み未発生 */ +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_TimerStart + + Description: start timer for measure timeout. + タイムアウト計測を開始する + + Arguments: tim : ms単位のタイムアウト時間 + (50msを超える値の場合は50ms単位になる) + + Returns: None + *---------------------------------------------------------------------------*/ +static void SDCARD_TimerStart(u32 tim) +{ +#if (TARGET_OS_CTR == 1) + sta_alm( sdmc_alm_id, tim); + PRINTDEBUG( "Timer Started.\n"); +#else + OSTick tim_tick; + + tim_tick = OS_MilliSecondsToTicks( tim); //us単位からTick単位へ + + OS_CancelAlarm( &sdmc_alm); //アラーム破棄 + OS_SetAlarm( &sdmc_alm, tim_tick, SDCARD_Timer_irq, NULL); //アラームセット +#endif +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_TimerStop + + Description: stop timer + タイムアウト計測を停止する + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void SDCARD_TimerStop(void) +{ +#if (TARGET_OS_CTR == 1) + stp_alm( sdmc_alm_id); + PRINTDEBUG( "Timer Stopped.\n"); + + //memo:割り込み禁止状態にしてstp_almを呼んでも停止しないので注意 +#else + OS_DisableIrq(); + OS_CancelAlarm( &sdmc_alm); + OS_EnableIrq(); +#endif +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_Timer_irq + + Description: timer interrupt handler. + タイマー割り込みハンドラ + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void SDCARD_Timer_irq(void* arg) +{ +#if (SD_DEBUG_PRINT_ON == 1) + u16 tmp; + + PRINTDEBUG( ">>>Timer intr(Timeout)\n"); + + SDCARD_ErrStatus |= SDMC_ERR_FPGA_TIMEOUT; /* タイムアウトエラービットの設定 */ + + tmp = SD_INFO1; + PRINTDEBUG( "SD_INFO1 : 0x%x\n", tmp); + tmp = SD_INFO1_MASK; + PRINTDEBUG( "SD_INFO1_MASK : 0x%x\n", tmp); + tmp = SD_INFO2; + PRINTDEBUG( "SD_INFO2 : 0x%x\n", tmp); + tmp = SD_INFO2_MASK; + PRINTDEBUG( "SD_INFO2_MASK : 0x%x\n", tmp); + tmp = SD_ERR_STS1; + PRINTDEBUG( "SD_ERR_STS1 : 0x%x\n", tmp); +#if (CTR_DEF_ENVIRONMENT_DSEMU == 1) + *(vu16*)0x08030200 = 1; +#endif + tmp = SD_ERR_STS2; +#if (CTR_DEF_ENVIRONMENT_DSEMU == 1) + *(vu16*)0x08030200 = 0; +#endif + PRINTDEBUG( "SD_ERR_STS2 : 0x%x\n", tmp); + tmp = *(vu16 *)(SD_IF_BASE+0x00); + PRINTDEBUG( "SD_CNT : 0x%x\n", tmp); + tmp = SD_SECCNT; + PRINTDEBUG( "SD_SECCNT : 0x%x\n", tmp); +#endif + + + if(SDCARD_EndFlag == FALSE){ /* 転送処理完了フラグの確認(クリア?)*/ + SDCARD_EndFlag = TRUE; /* 転送処理完了フラグをセット */ + /* SD_TransEndFPGA(); */ /* カード転送の終了処理 */ + /* SD_StopTransmission(); */ /* カード転送終了設定 */ + /* SD_Init(); */ /* SD Cardインターフェース部をリセット&初期設定 */ + if(pSDCARD_info){ /* Nullチェック */ + pSDCARD_info->result = SDCARD_ErrStatus;/* SdmcResultInfo に情報設定 */ + pSDCARD_info->resid = (ulSDCARD_SectorCount - ulSDCARD_RestSectorCount) * + SDCARD_SectorSize; /* SdmcResultInfo に処理セクタ数設定 */ + } + } + + /**/ + PRINTDEBUG( "--Wup sdTsk(Time)--\n"); +#if (TARGET_OS_CTR == 1) + iwup_tsk( sdmc_tsk_id); + PRINTDEBUG( "id : 0x%x\n", sdmc_tsk_id); +#else +// OS_WakeupThreadDirect( &sdmc_tsk); +// OS_WakeupThread( &sdmc_tsk_q); +#endif +} + + +/*---------------------------------------------------------------------------* + Name: i_sdmcSendSCR + + Description: get SCR register. + SCRを取得する(DATライン経由で8バイト送られてくる)。 + MultiBlock R/W と異なり、DATライン経由で転送されてくるSDカードの + レジスタは、MSBから先に送られてくることに注意。 + (Physical Layer Specification 2.00 p12-13参照) + + Arguments: None + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static u16 i_sdmcSendSCR(void) +{ + SDMC_ERR_CODE SaveErrStatus; /* エラーステータス保存用 */ + u32 SaveStatus; /* カードステータス保存用 */ + u32 ulSave_SectorSize; /* セクタサイズ保存用 */ + + SD_EnableClock(); /* SD-CLK Enable */ + + /* ブロックサイズの設定 */ + ulSave_SectorSize = SDCARD_SectorSize; /* セクタサイズの保存 */ + SDCARD_SectorSize = 8; /* SCR レジスタ 転送サイズ 8bytes */ + SD_SetBlockLength(SDCARD_SectorSize); /* SDカードデータ転送サイズ 8byte 設定 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?)*/ + return SDCARD_ErrStatus; + } + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RW_TIMEOUT); /* タイムアウト判定用タイマスタート */ +#endif + + if(SD_AppCommand()){ /* RCA設定後 CMD55発行処理が正常終了しない? */ + SD_DisableClock(); /* SD-CLK Disable */ + return SDCARD_ErrStatus; /* エラー終了 */ + } + +/* func_SDCARD_CallBack = NULL; */ + pSDCARD_info = NULL; + ulSDCARD_RestSectorCount = ulSDCARD_SectorCount = 1; /* 残りセクタサイズ、セクタカウントに1を設定 */ + pSDCARD_BufferAddr = SD_SCR; /* データ格納バッファのアドレスを設定 */ + + /* 転送前の準備処理 */ + SDCARD_ATC0_Flag = FALSE; /* 全ATC完了フラグクリア */ + SDCARD_FPGA_Flag = FALSE; /* FPGA処理完了フラグクリア */ + SDCARD_EndFlag = FALSE; /* 転送処理完了フラグクリア */ + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスのクリア */ + +#if SCR + thread_flag = TRUE; + SD_SendSCR(); /* SCRの取得コマンド発行 */ + PRINTDEBUG( "--Slp Tsk--\n"); + +// OS_SleepThread( NULL); +// OS_SleepThread( &sdmc_tsk_q); + + PRINTDEBUG( "waked\n"); + thread_flag = FALSE; + + while(!SDCARD_EndFlag){ /* カードアクセス終了待ち */ + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか確認 */ + return SDCARD_ErrStatus; + } + } + + if(!(SDCARD_ErrStatus & SDMC_ERR_R1_STATUS)){ /* コマンドレスポンス(R1)のカードステータスがエラーでないか確認 */ + SD_CheckStatus(FALSE); /* コマンドレスポンス(R1)の Card Status チェック */ + if(!(SDCARD_ErrStatus & SDMC_ERR_R1_STATUS)){ /* コマンドレスポンス(R1)のカードステータスがエラーでないか確認 */ + SD_SendStatus(); /* カードステータスの取得コマンド発行処理 */ + SD_CheckStatus(FALSE); /* コマンドレスポンス(R1)の Card Status チェック */ + } + } + SaveStatus = SDCARD_Status; /* カードステータスの保存 */ + SaveErrStatus = SDCARD_ErrStatus; /* エラーステータスの保存 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?)*/ + i_sdmcErrProcess(); /* エラー時の処理 */ + } + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか確認 */ + return SDCARD_ErrStatus; + } + SDCARD_Status = SaveStatus; /* カードステータスの復帰 */ + SDCARD_ErrStatus = SaveErrStatus; /* エラーステータスの復帰 */ +#endif + + SDCARD_SectorSize = ulSave_SectorSize; /* 保存していたセクタサイズを戻す(default:512bytes)*/ + SD_SetBlockLength(SDCARD_SectorSize); /* SDカードデータ転送サイズ 512bytes 設定 */ + + SD_DisableClock(); /* SD-CLK Disable */ + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: i_sdmcErrProcess + + Description: when error is occured, get Card Status to check and stop the + transfer. + エラー発生時の処理。カードステータスを取得し、データ転送中で + あればストップさせる。 + + Arguments: None + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static u16 i_sdmcErrProcess(void) +{ + u16 usRSP0; + + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスのクリア */ + + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_ERRPROC_TIMEOUT); /* タイムアウト判定用タイマスタート(2000msec) */ +#endif + + SD_SendStatus(); /* CMD13 addressed card sends its status register 発行、レスポンス待ち */ + + if(!SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?)*/ + SD_GetFPGA( usRSP0, SD_RSP0); + usRSP0 = (u16)(( usRSP0 & RSP_R1_CURRENT_STATE) >> 1); /* カレントステートを取り出す */ + if((usRSP0 == CURRENT_STATE_DATA) || (usRSP0 == CURRENT_STATE_RCV)){ /* SDCARD Status が data rcv の時 */ + SD_Command(SD_CMD_CMD | STOP_TRANSMISSION); /* CMD12(StopTransmission)発行処理 */ + } + } + + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + + return SDCARD_ErrStatus; +} + + +/*---------------------------------------------------------------------------* + Name: sdmcGetCardSize + + Description: get card size (number of sectors). + カードのセクタ数を取得する + + Arguments: None + + Returns: number of sectors in the SD card which inserted. + *---------------------------------------------------------------------------*/ +u32 sdmcGetCardSize(void) +{ + /* カード全セクタ数 (SDCARD_Layer_Init関数内で算出される) */ + return ulSDCARD_Size; +} + + +/*---------------------------------------------------------------------------* + Name: SDCARD_SD_Status + + Description: get SD Status. + SDステータスを取得する(DATライン経由で64バイト送られてくる)。 + カードステータスではないことを留意。 + MultiBlock R/W と異なり、DATライン経由で転送されてくるSDカードの + レジスタは、MSBから先に送られてくることに注意。 + (Physical Layer Specification 2.00 p12-13参照) + + Arguments: None + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static u16 SDCARD_SD_Status(void) +{ + SDMC_ERR_CODE SaveErrStatus; /* エラーステータス保存用 */ + u32 SaveStatus; /* カードステータス保存用 */ + u32 ulSave_SectorSize; /* セクタサイズ保存用 */ + u32 ulSaveRestSectorCount; /* 残りセクタサイズ保存用 */ + + SD_EnableClock(); /* SD-CLK Enable */ + + /* ブロックサイズの設定 */ + ulSave_SectorSize = SDCARD_SectorSize; /* セクタサイズの保存 */ + SDCARD_SectorSize = 64; /* SD_STATUS 転送サイズ 64bytes */ + SD_SetBlockLength(SDCARD_SectorSize); /* SDカードデータ転送サイズ 64byte 設定 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?)*/ + return SDCARD_ErrStatus; + } + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RW_TIMEOUT); /* タイムアウト判定用タイマスタート(4000msec) */ +#endif + + if(SD_AppCommand()){ /* RCA設定後 CMD55発行処理 が正常終了しない?*/ + SD_DisableClock(); /* SD-CLK Disable */ + return SDCARD_ErrStatus; /* エラー終了 */ + } + +/* func_SDCARD_CallBack = NULL; */ + pSDCARD_info = NULL; + ulSaveRestSectorCount = ulSDCARD_RestSectorCount; /* 残りセクタサイズを保存(TODO:いらない?) */ + ulSDCARD_RestSectorCount = ulSDCARD_SectorCount = 1; /* 残りセクタサイズ、セクタカウントを1に設定 */ + pSDCARD_BufferAddr = SD_SDSTATUS; /* データ格納バッファのアドレスを設定 */ + + /* 転送前の準備処理 */ + SDCARD_ATC0_Flag = FALSE; /* 全ATC完了フラグクリア */ + SDCARD_FPGA_Flag = FALSE; /* FPGA処理完了フラグクリア */ + SDCARD_EndFlag = FALSE; /* 転送処理完了フラグクリア */ + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスのクリア */ + + thread_flag = TRUE; + SD_SDStatus(); /* ACMD13 SD_STATUSの取得コマンド発行処理 */ + PRINTDEBUG( "--Slp Tsk--\n"); + +// OS_SleepThread( NULL); +// OS_SleepThread( &sdmc_tsk_q); + + PRINTDEBUG( "waked\n"); + thread_flag = FALSE; + + while(!SDCARD_EndFlag){ /* カードアクセス終了待ち */ + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか確認 */ + return SDCARD_ErrStatus; + } + } + + if(!(SDCARD_ErrStatus & SDMC_ERR_R1_STATUS)){ /* コマンドレスポンス(R1)のカードステータスが何らかのエラーでないか確認 */ + SD_CheckStatus(FALSE); /* コマンドレスポンス(R1)の Card Status チェック */ + if(!(SDCARD_ErrStatus & SDMC_ERR_R1_STATUS)){ /* コマンドレスポンス(R1)のカードステータスがエラーでないか確認 */ + SD_SendStatus(); /* カードステータス取得コマンド発行、レスポンス(R1)待ち */ + SD_CheckStatus(FALSE); /* コマンドレスポンス(R1)の Card Status チェック */ + } + } + SaveStatus = SDCARD_Status; /* カードステータスの保存 */ + SaveErrStatus = SDCARD_ErrStatus; /* エラーステータスの保存 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?)*/ + i_sdmcErrProcess(); /* エラー時の処理 */ + } + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか確認 */ + return SDCARD_ErrStatus; + } + SDCARD_Status = SaveStatus; /* カードステータスの復帰 */ + SDCARD_ErrStatus = SaveErrStatus; /* エラーステータスの復帰 */ + + SDCARD_SectorSize = ulSave_SectorSize; /* 保存していたセクタサイズを戻す(default:512bytes)*/ + SD_SetBlockLength(SDCARD_SectorSize); /* SDカードデータ転送サイズ 512bytes 設定 */ + ulSDCARD_RestSectorCount = ulSaveRestSectorCount; /* 保存していた残りセクタサイズを戻す(TODO:いらない?)*/ + + SD_DisableClock(); /* SD-CLK Disable */ + + return SDCARD_ErrStatus; +} + +/*******************************************************************************/ +int MMCP_SetBusWidth( BOOL b4bit) +{ + u32 ulSave_SectorSize; /* セクタサイズ保存用 */ +// u16 TestData; + u16 Resid; + + SD_EnableClock(); /* SD-CLK Enable */ + +#if 0 + TestData = 0x5A;//0xA5; + + /* ブロックサイズの設定 */ + ulSave_SectorSize = SDCARD_SectorSize; /* セクタサイズの保存 */ + SDCARD_SectorSize = 4; /* 転送サイズ 1バイト */ + SD_SetBlockLength( SDCARD_SectorSize); /* SDカードデータ転送サイズ 1byte 設定 */ +#endif + /*コマンド6発行*/ + MMCP_WriteBusWidth( b4bit); + SD_AndFPGA(SD_OPTION,(~SD_OPTION_WIDTH_1BIT)); /* IPにビット幅の設定(4bit幅) */ + +#if 0 + /**/ + pSDCARD_info = NULL; + ulSDCARD_RestSectorCount = ulSDCARD_SectorCount = 1; + pSDCARD_BufferAddr = &TestData; /* データ格納バッファのアドレスを設定 */ + SDCARD_ATC0_Flag = FALSE; /* 全ATC完了フラグクリア */ + SDCARD_FPGA_Flag = FALSE; /* FPGA処理完了フラグクリア */ + SDCARD_EndFlag = FALSE; /* 転送処理完了フラグクリア */ + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスのクリア */ + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RW_TIMEOUT); /* タイムアウト判定用タイマスタート(4000msec) */ +#endif + + /* IPのSD_SECCNTレジスタ有効化、転送セクタ数設定(自動CMD12発行のため) */ +// SD_EnableSeccnt( ulSDCARD_RestSectorCount); + + /*バステスト*/ + MMCP_BusTest( FALSE); + + /**/ + while( !SDCARD_EndFlag) { /* カードアクセス終了待ち */ + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか? */ + return SDCARD_ErrStatus; /* エラー終了 */ + } + } + + + /**/ + ulSDCARD_RestSectorCount = ulSDCARD_SectorCount = 1;/* 残りセクタサイズ、セクタカウントに1を設定 */ + pSDCARD_BufferAddr = &Resid; /* データ格納バッファのアドレスを設定 */ + SDCARD_ATC0_Flag = FALSE; /* 全ATC完了フラグクリア */ + SDCARD_FPGA_Flag = FALSE; /* FPGA処理完了フラグクリア */ + SDCARD_EndFlag = FALSE; /* 転送処理完了フラグクリア */ + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスのクリア */ + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RW_TIMEOUT); /* タイムアウト判定用タイマスタート(4000msec) */ +#endif + + /**/ + MMCP_BusTest( TRUE); + + /**/ + while( !SDCARD_EndFlag) { /* カードアクセス終了待ち */ + if( SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか? */ + return SDCARD_ErrStatus; /* エラー終了 */ + } + } + + /*バステスト合格ならバス幅を4bitに拡張*/ +// if( TestData == (~(Resid))) { + if( Resid == 0xA5) { + SD_AndFPGA(SD_OPTION,(~SD_OPTION_WIDTH_1BIT)); /* IPにビット幅の設定(4bit幅) */ + }else{ + SD_OrFPGA(SD_OPTION,(SD_OPTION_WIDTH_1BIT)); /* IPにビット幅の設定(1bit幅) */ + } + + SDCARD_SectorSize = ulSave_SectorSize; /* 保存していたセクタサイズを設定(デフォルト 512bytesに戻す)*/ + SD_SetBlockLength( SDCARD_SectorSize); /* SDカードデータ転送サイズ 512bytes 設定 */ +#endif + return( 0); +} +/*******************************************************************************/ + + +/*---------------------------------------------------------------------------* + Name: i_sdmcCheckWP + + Description: check the write protect bit in the SD_INFO1 register. + SD_INFO1レジスタのライトプロテクトビットを調べる + (0:ライトプロテクトされている、1:ライトプロテクトされていない)。 + CTRではポート1は常に1。 + + Arguments: None + + Returns: number of sectors in the SD card which inserted. + *---------------------------------------------------------------------------*/ +static u16 i_sdmcCheckWP(void) +{ + if (SD_port_number == SDCARD_PORT0) /* ポート0のとき */ + { + if(!(SD_CheckFPGAReg(SD_INFO1,SD_INFO1_WRITEPROTECT))) { //WPフラグが立っていないか? + SDCARD_ErrStatus |= SDMC_ERR_WP; //エラーフラグのWPエラービットを立てる + }else{ //WPフラグが立っていたとき + SDCARD_ErrStatus &= ~SDMC_ERR_WP; //エラーフラグのWPエラービットを落とす + } + return SDCARD_ErrStatus; + } + else if (SD_port_number == SDCARD_PORT1) /* ポート1のとき */ + { + if(!(SD_CheckFPGAReg(EXT_WP,EXT_WP_PORT1))) { //WPフラグが立っていないか? + SDCARD_ErrStatus |= SDMC_ERR_WP; //エラーフラグのWPエラービットを立てる + }else{ //WPフラグが立っていたとき + SDCARD_ErrStatus &= ~SDMC_ERR_WP; //エラーフラグのWPエラービットを落とす + } + return SDCARD_ErrStatus; + } + return SDMC_ERR_END; //ここには来ない +} + +/*---------------------------------------------------------------------------* + Name: sdmcWriteFifo + + Description: write to card. + ラッパーのFIFOを使用してカードへの書き込み。 + + Arguments: buf : 書き込みデータが格納されているバッファのアドレス + bufsize : 書き込むサイズ(セクタ数) + offset : 書き込み開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcWriteFifo(void* buf,u32 bufsize,u32 offset,void(*func)(),SdmcResultInfo *info) +{ + SDCARDMsg SdMsg; +#if (TARGET_OS_CTR == 1) + u32 recv_dat; +#else + OSMessage recv_dat; +#endif + SDMC_ERR_CODE api_result; + + SdMsg.buf = buf; + SdMsg.bufsize = bufsize; + SdMsg.offset = offset; + SdMsg.func = func; + SdMsg.info = info; + SdMsg.operation = SD_OPERATION_WRITE_WITH_FIFO; + +// recv_dat = (OSMessage)&SdMsg; + api_result = SDCARD_Thread( &SdMsg); +// OS_SendMessage( &sdmc_dtq, recv_dat, OS_MESSAGE_BLOCK); + + /* 返り値待ち */ +// OS_ReceiveMessage( &sdmc_result_dtq, &recv_dat, OS_MESSAGE_BLOCK); +// api_result = (SDMC_ERR_CODE)recv_dat; + + return api_result; +} + +/*---------------------------------------------------------------------------* + Name: SDCARDi_WriteFifo + + Description: write to card. + ラッパーのFIFOを使用してカードへの書き込み。 + + Arguments: buf : 書き込みデータが格納されているバッファのアドレス + bufsize : 書き込むサイズ(セクタ数) + offset : 書き込み開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE SDCARDi_WriteFifo(void* buf,u32 bufsize,u32 offset,void(*func)(),SdmcResultInfo *info) +{ + SDMC_ERR_CODE result; + + /* FIFO割り込み禁止 */ + *(SDIF_CNT) = (*(SDIF_CNT) & (~(SDIF_CNT_FFIE | SDIF_CNT_FEIE))); + *(SDIF_FDS) = (u16)SDCARD_SectorSize; /* FIFOのデータサイズ */ + *(SDIF_FSC) = bufsize; + *(SDIF_CNT) |= SDIF_CNT_USEFIFO; /* FIFO使用フラグON */ + CC_EXT_MODE = CC_EXT_MODE_DMA; /* DMAモードON */ + + result = SDCARDi_Write( buf, bufsize, offset, func, info); + + /* FIFO無効に */ + *(SDIF_CNT) &= (~SDIF_CNT_USEFIFO); /* FIFO使用フラグOFF */ + CC_EXT_MODE = CC_EXT_MODE_PIO; /* PIOモード(DMAモードOFF) */ + + return result; +} + +/*---------------------------------------------------------------------------* + Name: sdmcWrite + + Description: write to card. + カードへの書き込み。 + + Arguments: buf : 書き込みデータが格納されているバッファのアドレス + bufsize : 書き込むサイズ(セクタ数) + offset : 書き込み開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcWrite(void* buf,u32 bufsize,u32 offset,void(*func)(),SdmcResultInfo *info) +{ + SDCARDMsg SdMsg; +#if (TARGET_OS_CTR == 1) + u32 recv_dat; +#else + OSMessage recv_dat; +#endif + SDMC_ERR_CODE api_result; + + SdMsg.buf = buf; + SdMsg.bufsize = bufsize; + SdMsg.offset = offset; + SdMsg.func = func; + SdMsg.info = info; + SdMsg.operation = SD_OPERATION_WRITE; + +// recv_dat = (OSMessage)&SdMsg; + api_result = SDCARD_Thread( &SdMsg); +// OS_SendMessage( &sdmc_dtq, recv_dat, OS_MESSAGE_BLOCK); + + /* 返り値待ち */ +// OS_ReceiveMessage( &sdmc_result_dtq, &recv_dat, OS_MESSAGE_BLOCK); +// api_result = (SDMC_ERR_CODE)recv_dat; + + return api_result; +} + +/*---------------------------------------------------------------------------* + Name: SDCARDi_Write + + Description: write to card. + カードへの書き込み。 + + Arguments: buf : 書き込みデータが格納されているバッファのアドレス + bufsize : 書き込むサイズ(セクタ数) + offset : 書き込み開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE SDCARDi_Write(void* buf,u32 bufsize,u32 offset,void(*func)(),SdmcResultInfo *info) +{ + s16 nRetryCount; + u32 ulResid; + SDMC_ERR_CODE SaveErrStatus; /* エラーステータス保存用 */ + u32 SaveStatus; /* カードステータス保存用 */ + + if( func != NULL){ /* コールバック関数のNullチェック */ + return SDMC_ERR_PARAM; /* コマンドパラメータエラー */ + } + +#if WP_ena + if( i_sdmcCheckWP()) { + return SDMC_ERR_WP; /*** ライトプロテクトのチェック ***/ + } +#endif + for(nRetryCount = 0;nRetryCount < SDCARD_RETRY_COUNT;nRetryCount++){ + + SD_EnableClock(); /* SD-CLK Enable */ + +/* func_SDCARD_CallBack = func; */ + pSDCARD_info = info; + ulSDCARD_RestSectorCount = ulSDCARD_SectorCount = bufsize; + pSDCARD_BufferAddr = buf; /* データ格納バッファのアドレスを設定 */ + + SDCARD_ATC0_Flag = FALSE; /* 全ATC完了フラグクリア */ + SDCARD_FPGA_Flag = FALSE; /* FPGA処理完了フラグクリア */ + SDCARD_EndFlag = FALSE; /* 転送処理完了フラグクリア */ + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスのクリア */ + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RW_TIMEOUT); /* タイムアウト判定用タイマスタート(4000msec) */ +#endif + + /* IPのSD_SECCNTレジスタ有効化、転送セクタ数設定(自動CMD12発行のため) */ + SD_EnableSeccnt( ulSDCARD_RestSectorCount); + + /*--- ライトコマンド発行 ---*/ + if( SDCARD_SDHCFlag) { + SD_MultiWriteBlock( offset); /* ライトコマンド発行(引数:オフセット) */ + }else{ + SD_MultiWriteBlock( offset * SDCARD_SectorSize); /* ライトコマンド発行(引数:オフセット*セクタサイズ) */ + } + /*--------------------------*/ + + /**/ + while( !SDCARD_EndFlag) { /* カードアクセス終了待ち */ + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか? */ + return SDCARD_ErrStatus; /* エラー終了 */ + } + } + + /* エラーが発生していないか、タイムアウト以外のエラーの場合 */ + if(!(SDCARD_ErrStatus & SDMC_ERR_R1_STATUS)){ /* コマンドレスポンス(R1)のカードステータスがエラーでないか確認 */ + SD_CheckStatus(FALSE); /* コマンドレスポンス(R1)の Card Status チェック */ + if(!(SDCARD_ErrStatus & SDMC_ERR_R1_STATUS)){ /* コマンドレスポンス(R1)のカードステータスがエラーでないか確認 */ + SD_SendStatus(); /* カードステータスの取得コマンド発行処理 */ + SD_CheckStatus(FALSE); /* コマンドレスポンス(R1)の Card Status チェック */ + } + } + SaveStatus = SDCARD_Status; /* カードステータスの保存 */ + SaveErrStatus = SDCARD_ErrStatus; /* エラーステータスの保存 */ + if( SDCARD_ErrStatus) { /* エラーステータスの確認(エラー有り?)*/ + i_sdmcErrProcess(); /* エラー時の処理(status取得、強制停止) */ + } + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか確認 */ + return SDCARD_ErrStatus; /* エラー終了 */ + } +#if RESID + if( SDCARD_SDFlag) { /* SDカード(MMCでない)の場合 */ + if( SDCARD_UseFifoFlag) { /*--- FIFOを使用しているときは ---*/ + *(SDIF_CNT) &= (~SDIF_CNT_USEFIFO); /* 一時的にFIFO未使用モードにする */ + CC_EXT_MODE = CC_EXT_MODE_PIO; + i_sdmcGetResid(&ulResid); /* 書き込み完了セクタ数の取得 */ + *(SDIF_CNT) |= SDIF_CNT_USEFIFO; /* FIFO使用モードに戻す */ + CC_EXT_MODE = CC_EXT_MODE_DMA; + }else{ /*--- FIFOを使用していないとき ---*/ + i_sdmcGetResid(&ulResid); /* 書き込み完了セクタ数の取得 */ + } + if(info){ + info->resid = ulResid * SDCARD_SectorSize;/*** pSDCARD_info->resid をinfo->resid に修正 柏 2000.08.31. ***/ + } + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか確認 */ + return SDCARD_ErrStatus; + } + } +#endif + SDCARD_Status = SaveStatus; /* カードステータスの復帰 */ + SDCARD_ErrStatus = SaveErrStatus; /* エラーステータスの復帰 */ +#if RESID + if( SDCARD_SDFlag) { /* SDカード(MMCでない)の場合 */ + if( bufsize != ulResid){ /* ライト済みセクタ数が正しくないか? */ + SD_SetErr( SDMC_ERR_NUM_WR_SECTORS); /* エラーフラグセット */ + } + } +#endif + if( SDCARD_ErrStatus == SDMC_NORMAL) { /* エラーステータスの確認(エラー無し?)*/ + break; + } + } + + SD_DisableClock(); /* クロック供給停止 */ + + return SDCARD_ErrStatus; +} + + +/*---------------------------------------------------------------------------* + Name: i_sdmcGetResid + + Description: get the numbers of the well written(without errors) blocks. + 書き込みが完了したセクタの数を取得する。 + + + Arguments: pResid : 書き込み完了セクタ数を返す変数へのポインタ + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static u16 i_sdmcGetResid(u32 *pResid) +{ + u16 Resid[2]; + u32 ulSave_SectorSize; /* セクタサイズ保存用 */ + + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスをクリア */ + + /* ブロックサイズの設定 */ + ulSave_SectorSize = SDCARD_SectorSize; /* セクタサイズの保存 */ + SDCARD_SectorSize = 4; /* 転送サイズ 4バイト */ + SD_SetBlockLength( SDCARD_SectorSize); /* SDカードデータ転送サイズ 4byte 設定 */ + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか? */ + return SDCARD_ErrStatus; + } + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RW_TIMEOUT); /* タイムアウト判定用タイマスタート(4000msec) */ +#endif + + if( SD_AppCommand()) { /* RCA設定後 CMD55発行処理 */ + return SDCARD_ErrStatus; /* エラー発生(CMD55が正常終了しない)なら戻る */ + } + +/* func_SDCARD_CallBack = NULL; */ + pSDCARD_info = NULL; + ulSDCARD_RestSectorCount = ulSDCARD_SectorCount = 1;/* 残りセクタサイズ、セクタカウントに1を設定 */ + pSDCARD_BufferAddr = Resid; /* データ格納バッファのアドレスを設定 */ + + SDCARD_ATC0_Flag = FALSE; /* 全ATC完了フラグクリア */ + SDCARD_FPGA_Flag = FALSE; /* FPGA処理完了フラグクリア */ + SDCARD_EndFlag = FALSE; /* 転送処理完了フラグクリア */ + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスのクリア */ + + thread_flag = TRUE; + /*--- ACMD22 ライト済みセクタ数取得コマンド発行 ---*/ + SD_SendNumWRSectors(); + /*-------------------------------------------------*/ + PRINTDEBUG( "--Slp Tsk--\n"); + +// OS_SleepThread( NULL); +// OS_SleepThread( &sdmc_tsk_q); + + PRINTDEBUG( "waked\n"); + thread_flag = FALSE; + + while( !SDCARD_EndFlag) { /* カードアクセス終了待ち */ + if( SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか? */ + return SDCARD_ErrStatus; /* エラー終了 */ + } + } + /* エラーが発生していないか、タイムアウト以外のエラーの場合 */ + if( SDCARD_ErrStatus) { /* (タイムアウト以外に)エラー発生か? */ + i_sdmcErrProcess(); /* エラー時の処理 */ + *pResid = 0L; /* ライト済みセクタ数に 0 を設定 */ + }else{ /* エラーが発生していない場合 */ + /* SDカードのレジスタはMSBから送られてくるため並べ替えを行う */ + Resid[1] = SD_SwapByte(&Resid[1]); /* 上位 1byte と下位 1byte を入れ替える */ + (((LELONG *)pResid)->dt2word.low) = Resid[1]; /* Resid[1]の設定 */ + Resid[0] = SD_SwapByte(&Resid[0]); /* 上位 1byte と下位 1byte を入れ替える */ + (((LELONG *)pResid)->dt2word.high) = Resid[0]; /* Resid[0]の設定 */ + } + + SDCARD_SectorSize = ulSave_SectorSize; /* 保存していたセクタサイズを設定(デフォルト 512bytesに戻す)*/ + SD_SetBlockLength( SDCARD_SectorSize); /* SDカードデータ転送サイズ 512bytes 設定 */ + /* SetBlockLengthでエラーが出たらどうする? */ + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_Restore_port0 + + Description: restore registers and variables of port0. + ポート0のレジスタや変数を復帰する。 + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void SDCARD_Restore_port0(void) +{ + /* registers */ + SD_SetFPGA( SD_CLK_CTRL, SD_CLK_CTRL_port0); + SD_SetFPGA( SD_OPTION, SD_OPTION_port0); + + /* variables */ + SDCARD_ErrStatus = SDCARD_ErrStatus_port0; + SD_RCA = SD_RCA0; + SDCARD_MMCFlag = SDCARD_MMCFlag_port0; + SDCARD_Status = SDCARD_Status_port0; + SDCARD_SDFlag = SDCARD_SDFlag_port0; + SDCARD_OutFlag = SDCARD_OutFlag_port0; + pSDCARD_info = pSDCARD_info_port0; + SDCARD_WP_PERMANENT = SDCARD_WP_PERMANENT_port0; + SDCARD_WP_TEMPORARY = SDCARD_WP_TEMPORARY_port0; + + /* registers */ +#if (TARGET_OS_CTR == 1) + miCpuCopy8( SD_CID_port0, SD_CID, 16); + miCpuCopy8( SD_CSD_port0, SD_CSD, 16); +#else + MI_CpuCopy8( SD_CID_port0, SD_CID, 16); + MI_CpuCopy8( SD_CSD_port0, SD_CSD, 16); +#endif +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_Restore_port1 + + Description: restore registers and variables of port0. + ポート1のレジスタや変数を復帰する。 + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void SDCARD_Restore_port1(void) +{ + /*registers*/ + SD_SetFPGA( SD_CLK_CTRL, SD_CLK_CTRL_port1); + SD_SetFPGA( SD_OPTION, SD_OPTION_port1); + + /*variables*/ + SDCARD_ErrStatus = SDCARD_ErrStatus_port1; + SD_RCA = SD_RCA1; + SDCARD_MMCFlag = SDCARD_MMCFlag_port1; + SDCARD_Status = SDCARD_Status_port1; + SDCARD_SDFlag = SDCARD_SDFlag_port1; + SDCARD_OutFlag = SDCARD_OutFlag_port1; + pSDCARD_info = pSDCARD_info_port1; + SDCARD_WP_PERMANENT = SDCARD_WP_PERMANENT_port1; + SDCARD_WP_TEMPORARY = SDCARD_WP_TEMPORARY_port1; + + /*registers*/ +#if (TARGET_OS_CTR == 1) + miCpuCopy8( SD_CID_port1, SD_CID, 16); + miCpuCopy8( SD_CSD_port1, SD_CSD, 16); +#else + MI_CpuCopy8( SD_CID_port1, SD_CID, 16); + MI_CpuCopy8( SD_CSD_port1, SD_CSD, 16); +#endif +} + + +/*---------------------------------------------------------------------------* + Name: i_sdmcSelectedNo + + Description: get selected port number. + 選択されているポート番号を取得する + + Arguments: None + + Returns: [15:8]port numbers which supported(サポートされているポート数) + [7:0]port number which selected now(選択されているポート番号) + *---------------------------------------------------------------------------*/ +static u16 i_sdmcSelectedNo(void) +{ + u16 i_sdmcSelect_Value; + + SD_GetFPGA(i_sdmcSelect_Value,SD_PORTSEL); /* SD_PORTSELレジスタ値を取得 */ + + return i_sdmcSelect_Value; +} + +/*---------------------------------------------------------------------------* + Name: i_sdmcSelect + + Description: select port. + ポートを選択する + + Arguments: select : [15:8]port numbers which supported(サポートされているポート数) + [7:0]port number which selected now(選択するポート番号) + Returns: 0 : success + >0 : error + *---------------------------------------------------------------------------*/ +static u16 i_sdmcSelect(u16 select) +{ + union + { + u16 Val; + struct + { + u8 L; /* 指定したいポート */ + u8 H; /* サポートされているポート */ + } PSel; + } SDCARD_PSel; + + //TODO : transferモードからstand-byモードにする? +/* if( !SDCARD_EndFlag) { // 転送が残っている場合はエラー + return SDMC_ERR_END; + } +*/ + SDCARD_PSel.Val = select; + if ((SDCARD_PSel.PSel.H > SDCARD_PORT_NO_MAX) + | (SDCARD_PSel.PSel.H < SDCARD_PORT_NO_MIN) + | (SDCARD_PSel.PSel.L > SDCARD_PORT_SELECT_NO)) + { + return SDMC_ERR_PARAM; /* コマンドパラメータエラー */ + }else{ + SD_port_en_numbers = SDCARD_PSel.PSel.H; /* 新しくサポートするポート数を保存 */ + SD_port_number = SDCARD_PSel.PSel.L; /* 新しく選択するポート番号を保存 */ + + SD_GetFPGA(SDCARD_PSel.Val,SD_PORTSEL); /* 現在のレジスタを取得 */ + + if (SDCARD_PSel.PSel.L == 0) /* 現在選択されているポートが 0 ? */ + { + SDCARD_Backup_port0(); + }else{ + SDCARD_Backup_port1(); + } + + SDCARD_PSel.Val= select; + + if (SDCARD_PSel.PSel.L == 0) /* 新しく選択されたポートが 0 ? */ + { + SDCARD_Restore_port0(); + }else{ + SDCARD_Restore_port1(); + } + + SD_SetFPGA(SD_PORTSEL,select); /* レジスタへセット */ + return SDMC_NORMAL; /* 0 リターン */ + } +} + + +/*---------------------------------------------------------------------------* + Name: SDCARD_Thread + + Description: SDメモリカードメインタスク + + Arguments: + + Returns: None + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE SDCARD_Thread( SDCARDMsg* SdMsg) +{ + SDMC_ERR_CODE api_result; + + while( TRUE) { + /* メッセージ待ち */ + PRINTDEBUG( "rcv mes sdThread\n"); + PRINTDEBUG( "sd task : receive command : %d\n", SdMsg->operation); + + switch( SdMsg->operation) { + case SD_OPERATION_INIT: + api_result = i_sdmcInit(); + break; + case SD_OPERATION_READ: + PRINTDEBUG( "from:0x%x, sectors:0x%x\n", SdMsg->offset, SdMsg->bufsize); + api_result = SDCARDi_Read( SdMsg->buf, SdMsg->bufsize, + SdMsg->offset, SdMsg->func, + SdMsg->info); + break; + case SD_OPERATION_READ_WITH_FIFO: + PRINTDEBUG( "from:0x%x, sectors:0x%x\n", SdMsg->offset, SdMsg->bufsize); + api_result = SDCARDi_ReadFifo( SdMsg->buf, SdMsg->bufsize, + SdMsg->offset, SdMsg->func, + SdMsg->info); + break; + case SD_OPERATION_WRITE: + PRINTDEBUG( "from:0x%x, sectors:0x%x\n", SdMsg->offset, SdMsg->bufsize); + api_result = SDCARDi_Write( SdMsg->buf, SdMsg->bufsize, + SdMsg->offset, SdMsg->func, + SdMsg->info); + break; + case SD_OPERATION_WRITE_WITH_FIFO: + PRINTDEBUG( "from:0x%x, sectors:0x%x\n", SdMsg->offset, SdMsg->bufsize); + api_result = SDCARDi_WriteFifo( SdMsg->buf, SdMsg->bufsize, + SdMsg->offset, SdMsg->func, + SdMsg->info); + break; + default: + PRINTDEBUG( "sdmc-thread error : undefined command.\n"); + api_result = SDMC_ERR_COMMAND; + break; + } + + PRINTDEBUG( "sd task : operation ends(result : 0x%x), send message begin\n", api_result); + + /*メッセージ返送*/ + return( api_result); + } +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_Intr_Thread + + Description: SDメモリカード割り込み処理タスク + + Arguments: + + Returns: None + *---------------------------------------------------------------------------*/ +static void SDCARD_Intr_Thread( void* arg) +{ + u16 sd_info1;//, sd_info2; + OSIntrMode enabled; + +// while( 1) { + PRINTDEBUG( "next_tsk:0x%x\n", OS_SelectThread()); + PRINTDEBUG( "Slp sdIntr\n"); + +/* OS_WaitInterrupt( FALSE, OS_IE_SD); + enabled = OS_DisableInterrupts(); + (void)OS_ClearIrqCheckFlag( OS_IE_SD); + (void)OS_RestoreInterrupts( enabled);*/ + //TODO! OS_SleepThread( NULL); + + PRINTDEBUG( "sdIntr waked\n"); + /*SD割り込みのIF解除*/ + *(vu16*)CTR_INT_IF = CTR_IE_SD_MASK; + + /*--- FIFOを使うとき ---*/ + if( SDCARD_UseFifoFlag) { + sd_info1 = SD_INFO1; + if( ((*SDIF_CNT & SDIF_CNT_FULL)&&(*SDIF_CNT & SDIF_CNT_FFIE)) || + ((!(*SDIF_CNT & SDIF_CNT_NEMP))&&(*SDIF_CNT & SDIF_CNT_FEIE))) { + + PRINTDEBUG( ">>>SD Intr(FIFO)\n");// Full or Empty)\n"); + + OS_DisableIrqMask( OS_IE_SD); + + SDCARD_FPGA_irq(); /*カードからのリードライト要求割り込み*/ + OS_EnableIrqMask( OS_IE_SD); + + /* FIFO割り込みとALLEND割り込みがほぼ同時の場合に対応 */ + if( SD_CheckFPGAReg( sd_info1, SD_INFO1_ALL_END)) { + OS_DisableIrqMask( OS_IE_SD); + + SYSFPGA_irq(); + OS_EnableIrqMask( OS_IE_SD); + } + }else{ + if( SD_CheckFPGAReg( SD_INFO2, (SD_INFO2_MASK_BRE | SD_INFO2_MASK_BWE))) { + PRINTDEBUG( ">>>SD Intr(R/W Req)\n"); + //ここで自動的にラッパーのFIFO<->SD_BUF0間で通信が行われる + // if((!(*SDIF_CNT & SDIF_CNT_NEMP))&&(*SDIF_CNT & SDIF_CNT_FEIE)) { + OS_DisableIrqMask( OS_IE_SD); + + PRINTDEBUG( "begin\n"); + SDCARD_FPGA_irq(); + PRINTDEBUG( "end\n"); + OS_EnableIrqMask( OS_IE_SD); + }else{ + PRINTDEBUG( ">>>SD Intr(End or Err)\n"); + OS_DisableIrqMask( OS_IE_SD); + + SYSFPGA_irq(); /*完了またはエラー割り込み*/ + OS_EnableIrqMask( OS_IE_SD); + /**/ + } + } + /*--- FIFOを使わないとき ---*/ + }else{ + if( SD_CheckFPGAReg( SD_INFO2, (SD_INFO2_MASK_BRE | SD_INFO2_MASK_BWE))) { + PRINTDEBUG( ">>>SD Intr(R/W Req)\n"); + OS_DisableIrqMask( OS_IE_SD); + + PRINTDEBUG( "begin\n"); + SDCARD_FPGA_irq(); /*カードからのリードライト要求割り込み*/ + PRINTDEBUG( "end\n"); + OS_EnableIrqMask( OS_IE_SD); + }else{ + PRINTDEBUG( ">>>SD Intr(End or Err)\n"); + OS_DisableIrqMask( OS_IE_SD); + SYSFPGA_irq(); /*完了またはエラー割り込み*/ + OS_EnableIrqMask( OS_IE_SD); + /**/ + } + } +// } +} diff --git a/build/libraries/devices/rom_sdmc/ARM7/sdmc_config.h b/build/libraries/devices/rom_sdmc/ARM7/sdmc_config.h new file mode 100644 index 0000000..2530111 --- /dev/null +++ b/build/libraries/devices/rom_sdmc/ARM7/sdmc_config.h @@ -0,0 +1,85 @@ +/* +** Copyright (c) 2000-2001 Matsushita Electric Industrial Co., Ltd. +** All Rights Reserved. +*/ + +/* +** $System IP1.1 without C2 サンプルソフト +** $Subsystem カードドライバ +** $Filename CARDDRV.H +** $Version 1.0 版 +** $Date 01/02/16 +** $Log 01/02/16 rev1.0作成 +** 松下電器産業(株)半導体開発本部 +*/ + + +#ifndef __SDMC_CONFIG_H__ +#define __SDMC_CONFIG_H__ + + +#include + +#ifdef USE_OS +#include /* IP 対応レジスタ定義 */ +#endif + + + +/********************************************* + ターゲットOS +*********************************************/ +#define TARGET_OS_CTR (0) +#define TARGET_OS_NITRO (TARGET_OS_CTR ^ 1) + + +/********************************************* + SDドライバ コンフィグレーション +*********************************************/ +#define SD_DEBUG_PRINT_ON 0 /* デバッグ表示 */ + +#define WP_ena 1 /* ライトプロテクトのチェック有効 */ +#define TIMEOUT 1 /* FPGA Timeout none = FALSE */ +#define SCR 1 /* Send SCR Command = TRUE */ +#define RESID 1 /* Write Error Resid enable = TRUE */ +#define ATC_ON 0 /* ATC転送 使用/未使用 */ + +#define SecEnable 1 /* SD_SECCNTレジスタ Enable */ +#define SecDisenable 0 /* SD_SECCNTレジスタ Disable */ +//#define STANDBYMODE 0x04 /*** 5772 standby control bit ***/ + + +/********************************************* + タイムアウト設定値(ms単位) +*********************************************/ +#define SDCARD_RW_TIMEOUT (4000) +#define SDCARD_STDBY_TIMEOUT (50) +#define SDCARD_CLOCK_WAIT (500) +#define SDCARD_SDCLK_WAIT (10) +#define SDCARD_INITIAL_TIMEOUT (800) +#define SDCARD_RESET_TIMEOUT (1500) +#define SDCARD_ERASE_TIMEOUT (1) +#define SDCARD_ERRPROC_TIMEOUT (2000) + + +/********************************************* + リトライ回数(Multiple Block R/W のとき) +*********************************************/ +#define SDCARD_RETRY_COUNT (3) + +/********************************************* + その他 +*********************************************/ +#define SECTOR_SIZE (512) /* 1セクタのバイト数 */ +#define SECTOR_MAX (255) /* SYSFPGA アクセス最大セクタ数 */ + +/*--- 上位レイヤに返すステータス値(SDCARD_Getstatus参照)用 ---*/ +#define SDCARD_FLAG_CLR (0x3FFF) /* カード判定部分クリア用 */ +#define SDCARD_FLAG_SD (0x8000) /* カード判定部分SDカード */ +#define SDCARD_FLAG_MMC (0x4000) /* カード判定部分MMCカード */ +#define SDCARD_PORT1_CLR (0x0007) /* カードポート1判定部分クリア用 */ + + + + +#endif /*__SDMC_CONFIG_H__*/ diff --git a/build/libraries/devices/rom_sdmc/Makefile b/build/libraries/devices/rom_sdmc/Makefile new file mode 100644 index 0000000..4f69ad1 --- /dev/null +++ b/build/libraries/devices/rom_sdmc/Makefile @@ -0,0 +1,34 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: TwlSDK - libraries - spi +# File: Makefile +# +# Copyright 2007 Nintendo. All rights reserved. +# +# These coded instructions, statements, and computer programs contain +# proprietary information of Nintendo of America Inc. and/or Nintendo +# Company Ltd., and are protected by Federal copyright law. They may +# not be disclosed to third parties or copied or duplicated in any form, +# in whole or in part, without the prior written consent of Nintendo. +# +# $Log: $ +# $NoKeywords: $ +#---------------------------------------------------------------------------- + +include $(TWLSDK_ROOT)/build/buildtools/commondefs + + +#---------------------------------------------------------------------------- + +# SUBDIRS = ARM9 + +ifdef TWL_WITH_ARM7 +SUBDIRS += ARM7 +endif + +#---------------------------------------------------------------------------- + +include $(TWLSDK_ROOT)/build/buildtools/modulerules + + +#===== End of Makefile ===== diff --git a/build/libraries/devices/sdmc/ARM7/sdif_reg.h b/build/libraries/devices/sdmc/ARM7/sdif_reg.h index 31011d9..1d9501b 100644 --- a/build/libraries/devices/sdmc/ARM7/sdif_reg.h +++ b/build/libraries/devices/sdmc/ARM7/sdif_reg.h @@ -20,11 +20,12 @@ (R/W) : readable and writable (RO) : read only *********************************************/ -#if (CTR_DEF_ENVIRONMENT_DSEMU == 1) +/*#if (CTR_DEF_ENVIRONMENT_DSEMU == 1) #define SD_IP_BASE (0x08030000) // NTR用ブレッドボード設定 #else #define SD_IP_BASE (0x400B0000) // IOP実機設定 -#endif +#endif*/ +#define SD_IP_BASE (0x04004800) // TWL ARM7設定 #define SD_CMD (*(vu16 *)(SD_IP_BASE + 0x00)) /* CMD発行レジスタ(R/W) */ @@ -65,11 +66,12 @@ /********************************************* SD I/F(ラッパー)レジスタ *********************************************/ -#if (CTR_DEF_ENVIRONMENT_DSEMU == 1) +/*#if (CTR_DEF_ENVIRONMENT_DSEMU == 1) #define SD_IF_BASE (0x08030100) // NTR用ブレッドボード設定 #else #define SD_IF_BASE (0x400B0100) // IOP実機設定 -#endif +#endif*/ +#define SD_IF_BASE (0x04004900) // IOP実機設定 #define SDIF_CNT ((vu32 *)(SD_IF_BASE+0x00)) /* コントロール */ @@ -91,7 +93,7 @@ /********************************************* INTCレジスタ *********************************************/ -#if (CTR_DEF_ENVIRONMENT_DSEMU == 1) +/*#if (CTR_DEF_ENVIRONMENT_DSEMU == 1) #define CTR_INT_BASE (0x08000000) #else #define CTR_INT_BASE (0x40010000) @@ -103,7 +105,14 @@ #define CTR_INT_IF (CTR_INT_BASE + 0x08) //IF #define CTR_IE_SD_MASK (1<<13) //SD割り込みフラグ +*/ +#define CTR_INT_BASE (0x04000000) +#define CTR_INT_SE (CTR_INT_BASE + 0x208) //割り込み要求選択レジスタ +#define CTR_INT_IE (CTR_INT_BASE + 0x218) //IE +#define CTR_INT_IF (CTR_INT_BASE + 0x21C) //IF + +#define CTR_IE_SD_MASK (1<<8) //SD割り込みフラグ #endif /* __SD_IP_REG_H__ */ diff --git a/build/libraries/devices/sdmc/ARM7/sdmc.c b/build/libraries/devices/sdmc/ARM7/sdmc.c index 11fe507..a7a8c57 100644 --- a/build/libraries/devices/sdmc/ARM7/sdmc.c +++ b/build/libraries/devices/sdmc/ARM7/sdmc.c @@ -12,7 +12,7 @@ #include "sdmc.h" #include "sdif_ip.h" /* IP 対応フラグ定義 */ -#if (SD_DEBUG_PRINT_ON == 1) +/*#if (SD_DEBUG_PRINT_ON == 1) #if (CTR_DEF_ENVIRONMENT_DSEMU == 1) #define PRINTDEBUG osTPrintf #else @@ -21,13 +21,14 @@ #endif #else #define PRINTDEBUG( ...) ((void)0) -#endif +#endif*/ + #define PRINTDEBUG OS_TPrintf /*********************************************************************** 定数 ***********************************************************************/ -#define SD_STACK_SIZE (4096) +#define SD_STACK_SIZE (4096*2) #define SD_THREAD_PRIO (10) #define SD_INTR_THREAD_PRIO (SD_THREAD_PRIO - 1) @@ -64,6 +65,7 @@ OSMessageQueue sdmc_result_dtq; OSMessage sdmc_result_dtq_array[1]; OSAlarm sdmc_alm; OSThread sdmc_intr_tsk; +OSThreadQueue sdmc_tsk_q; #endif #if (TARGET_OS_CTR == 1) @@ -106,9 +108,9 @@ static void SDCARD_Thread( void* arg); //SD static void SDCARD_Intr_Thread( void* arg); //SD割り込み処理スレッド SDMC_ERR_CODE sdmcGoIdle( void (*func1)(),void (*func2)()); -static SDMC_ERR_CODE i_sdmcInit( void); -static SDMC_ERR_CODE SDCARD_Layer_Init(void); -static SDMC_ERR_CODE i_sdmcMPInit( void); /* カードドライバ初期化(マルチポート対応) */ +/*static*/ SDMC_ERR_CODE i_sdmcInit( void); +/*static*/ SDMC_ERR_CODE SDCARD_Layer_Init(void); +/*static*/ SDMC_ERR_CODE i_sdmcMPInit( void); /* カードドライバ初期化(マルチポート対応) */ static u16 i_sdmcErrProcess(void); /* エラー時の処理 */ static u16 i_sdmcGetResid(u32 *pResid); /* 書きこみ完了セクタ数の取得 */ @@ -341,6 +343,8 @@ static void i_sdmcEnable( void) // osEnableInterrupts(); // *(vu16*)0x04000208 = 1; #else + /*SD割り込みのIF解除*/ + *(vu16*)CTR_INT_IF = CTR_IE_SD_MASK; OS_SetIrqFunction( OS_IE_SD, SDCARD_irq_Handler); OS_EnableIrqMask( OS_IE_SD); #endif @@ -376,7 +380,9 @@ void SDCARD_irq_Handler( void) #if (TARGET_OS_CTR == 1) iwup_tsk( sdmc_intr_tsk_id); #else - OS_WakeupThreadDirect( &sdmc_intr_tsk); + PRINTDEBUG( "SD irq!\n"); + OS_SetIrqCheckFlag( OS_IE_SD); +//TODO! OS_WakeupThreadDirect( &sdmc_intr_tsk); #endif } @@ -493,29 +499,35 @@ SDMC_ERR_CODE sdmcInit(void (*func1)(),void (*func2)()) } #else //(TARGET_OS_NITRO = 1) - /*---------- OS準備 ----------*/ - if( !OS_IsAlarmAvailable()) { /* アラームチェック(OS_InitAlarm済みか?) */ - SDCARD_ErrStatus |= SDMC_ERR_END; - }else{ - OS_CreateAlarm( &sdmc_alm); //使用可能であれば初期化 - } + /*---------- OS準備 ----------*/ + if( !OS_IsAlarmAvailable()) { /* アラームチェック(OS_InitAlarm済みか?) */ + SDCARD_ErrStatus |= SDMC_ERR_END; + }else{ + OS_CreateAlarm( &sdmc_alm); //使用可能であれば初期化 + } - /* メッセージ初期化 */ - OS_InitMessageQueue( &sdmc_dtq, &sdmc_dtq_array[0], 1); - OS_InitMessageQueue( &sdmc_result_dtq, &sdmc_result_dtq_array[0], 1); + /* メッセージ初期化 */ + OS_InitMessageQueue( &sdmc_dtq, &sdmc_dtq_array[0], 1); + OS_InitMessageQueue( &sdmc_result_dtq, &sdmc_result_dtq_array[0], 1); - OS_InitThread(); //自分の優先度が16になる +// OS_InitThread(); //自分の優先度が16になる - /* SDスレッドの立ち上げ */ - OS_CreateThread( &sdmc_tsk, SDCARD_Thread, NULL, - (sd_stack+SD_STACK_SIZE / sizeof(u64)), SD_STACK_SIZE, SD_THREAD_PRIO); - OS_WakeupThreadDirect( &sdmc_tsk); + /* SDスレッドの立ち上げ */ + OS_CreateThread( &sdmc_tsk, SDCARD_Thread, NULL, + (sd_stack+SD_STACK_SIZE / sizeof(u64)), SD_STACK_SIZE, SD_THREAD_PRIO); + OS_WakeupThreadDirect( &sdmc_tsk); + PRINTDEBUG( "sdmc_tsk:0x%x\n", &sdmc_tsk); + - /* SD割り込み処理スレッドの立ち上げ */ - OS_CreateThread( &sdmc_intr_tsk, SDCARD_Intr_Thread, NULL, - (sd_intr_stack+SD_STACK_SIZE / sizeof(u64)), SD_STACK_SIZE, SD_INTR_THREAD_PRIO); - OS_WakeupThreadDirect( &sdmc_intr_tsk); - /*----------------------------*/ + /* SD割り込み処理スレッドの立ち上げ */ + OS_CreateThread( &sdmc_intr_tsk, SDCARD_Intr_Thread, NULL, + (sd_intr_stack+SD_STACK_SIZE / sizeof(u64)), SD_STACK_SIZE, SD_INTR_THREAD_PRIO); + OS_WakeupThreadDirect( &sdmc_intr_tsk); + PRINTDEBUG( "sdmc_intr_tsk:0x%x\n", &sdmc_intr_tsk); + + /* スレッドキューの初期化 */ + OS_InitThreadQueue( &sdmc_tsk_q); + /*----------------------------*/ #endif /**/ sdmc_tsk_created = TRUE; @@ -582,7 +594,7 @@ SDMC_ERR_CODE sdmcGoIdle( void (*func1)(),void (*func2)()) Returns: 0 : success > 0 : error code *---------------------------------------------------------------------------*/ -static SDMC_ERR_CODE i_sdmcInit( void) +/*static*/ SDMC_ERR_CODE i_sdmcInit( void) { i_sdmcEnable(); @@ -665,7 +677,7 @@ SDMC_ERR_CODE sdmcReset( void) Returns: None *---------------------------------------------------------------------------*/ -static SDMC_ERR_CODE SDCARD_Layer_Init(void) +/*static*/ SDMC_ERR_CODE SDCARD_Layer_Init(void) { u32 ulCSize; // SYSTIM wait_tim, limit_tim; @@ -692,7 +704,8 @@ static SDMC_ERR_CODE SDCARD_Layer_Init(void) #if (TARGET_OS_CTR == 1) dly_tsk( 1); #else - OS_Sleep( 1); +// OS_Sleep( 1); + SVC_WaitByLoop( 17900); //179*4サイクル=716サイクル=10024ns=10us #endif SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスをクリア */ @@ -746,17 +759,17 @@ static SDMC_ERR_CODE SDCARD_Layer_Init(void) SDCARD_TimerStart(SDCARD_RESET_TIMEOUT); /* タイムアウト判定用タイマスタート */ #endif - PRINTDEBUG( " CMD0 (GO_IDLE_STATE)\n"); + PRINTDEBUG( " CMD0(GO_IDLE_STATE)\n"); SD_ClrErr((u16)(~SDMC_ERR_FPGA_TIMEOUT)); /* タイムアウト以外のエラーをクリア */ { -PRINTDEBUG( "SD_INFO1 : 0x%x\n", SD_INFO1); +/*PRINTDEBUG( "SD_INFO1 : 0x%x\n", SD_INFO1); PRINTDEBUG( "SD_INFO2 : 0x%x\n", SD_INFO2); PRINTDEBUG( "SD_INFO1_MASK : 0x%x\n", SD_INFO1_MASK); PRINTDEBUG( "SD_INFO2_MASK : 0x%x\n", SD_INFO2_MASK); PRINTDEBUG( "SD_CLK_CTRL : 0x%x\n", SD_CLK_CTRL); PRINTDEBUG( "SD_SIZE : 0x%x\n", SD_SIZE); -PRINTDEBUG( "SD_INFO1_MASK : 0x%x\n", (*(vu32 *)(SD_IP_BASE + 0x20))); +PRINTDEBUG( "SD_INFO1_MASK : 0x%x\n", (*(vu32 *)(SD_IP_BASE + 0x20)));*/ } SD_Command(SD_CMD_CMD | GO_IDLE_STATE); /* CMD0発行、レスポンス確認 */ if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ @@ -767,7 +780,8 @@ PRINTDEBUG( "SD_INFO1_MASK : 0x%x\n", (*(vu32 *)(SD_IP_BASE + 0x20))); #if (TARGET_OS_CTR == 1) dly_tsk( 1); /* 1ms待ち */ #else - OS_Sleep( 1); +// OS_Sleep( 1); + SVC_WaitByLoop( 17900); //179*4サイクル=716サイクル=10024ns=10us #endif SD_SendIfCond(); /* CMD8発行、レスポンス確認 */ if( !SDCARD_SDHCFlag) { /* SDHC以外は失敗してるはずなので */ @@ -818,6 +832,7 @@ PRINTDEBUG( "SD_INFO1_MASK : 0x%x\n", (*(vu32 *)(SD_IP_BASE + 0x20))); #if TIMEOUT SDCARD_TimerStart(SDCARD_INITIAL_TIMEOUT); /* タイムアウト判定用タイマスタート */ #endif +PRINTDEBUG( "%d\n", __LINE__); SD_SendCID(); /* CMD2発行 レスポンス確認 */ if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ @@ -835,7 +850,7 @@ PRINTDEBUG( "SD_INFO1_MASK : 0x%x\n", (*(vu32 *)(SD_IP_BASE + 0x20))); } /*------- standby state -------*/ - +PRINTDEBUG( "%d\n", __LINE__); SD_SendCSD(); /* CMD9発行 レスポンス確認 */ if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ return SDCARD_ErrStatus; @@ -865,6 +880,7 @@ PRINTDEBUG( "SD_INFO1_MASK : 0x%x\n", (*(vu32 *)(SD_IP_BASE + 0x20))); #if SCR SD_SelectBitWidth(FALSE); /* CMD55->ACMD6 ビット幅の選択 1bit */ +PRINTDEBUG( "%d\n", __LINE__); /* ACMD51 発行 SD configuration register (SCR) */ if(SDCARD_SDFlag){ /* SDカードフラグ ON かチェック */ @@ -962,7 +978,7 @@ PRINTDEBUG( "SD_INFO1_MASK : 0x%x\n", (*(vu32 *)(SD_IP_BASE + 0x20))); Returns: 0 : success > 0 : error code *---------------------------------------------------------------------------*/ -static SDMC_ERR_CODE i_sdmcMPInit( void) +/*static*/ SDMC_ERR_CODE i_sdmcMPInit( void) { if(((SD_port_number == SDCARD_PORT0) && (!SD_CheckFPGAReg(SD_INFO1,SD_INFO1_DETECT))) || ((SD_port_number == SDCARD_PORT1) && (!SD_CheckFPGAReg(EXT_CD,EXT_CD_PORT1_DETECT))) || @@ -1257,12 +1273,13 @@ static SDMC_ERR_CODE SDCARDi_Read(void* buf,u32 bufsize,u32 offset,void(*func)(v /*--------------------------*/ /**/ - PRINTDEBUG( "----- Sleep Thread -----\n"); - //can_wup( 0); + PRINTDEBUG( "--Slp Tsk--\n"); #if (TARGET_OS_CTR == 1) + //can_wup( 0); slp_tsk(); #else - OS_SleepThread( NULL); +// OS_SleepThread( NULL); + OS_SleepThread( &sdmc_tsk_q); #endif PRINTDEBUG( "waked\n"); @@ -1556,7 +1573,7 @@ static void SDCARD_TimerStart(u32 tim) #else OSTick tim_tick; - tim_tick = OS_MicroSecondsToTicks( tim); //us単位からTick単位へ + tim_tick = OS_MilliSecondsToTicks( tim); //us単位からTick単位へ OS_CancelAlarm( &sdmc_alm); //アラーム破棄 OS_SetAlarm( &sdmc_alm, tim_tick, SDCARD_Timer_irq, NULL); //アラームセット @@ -1602,7 +1619,7 @@ static void SDCARD_Timer_irq(void* arg) #if (SD_DEBUG_PRINT_ON == 1) u16 tmp; - PRINTDEBUG( ">>>>> Timer interrupt (Timeout)\n"); + PRINTDEBUG( ">>>Timer intr(Timeout)\n"); SDCARD_ErrStatus |= SDMC_ERR_FPGA_TIMEOUT; /* タイムアウトエラービットの設定 */ @@ -1644,12 +1661,13 @@ static void SDCARD_Timer_irq(void* arg) } /**/ - PRINTDEBUG( "----- Wakeup Thread -----\n"); + PRINTDEBUG( "--Wup sdTsk(Time)--\n"); #if (TARGET_OS_CTR == 1) iwup_tsk( sdmc_tsk_id); PRINTDEBUG( "id : 0x%x\n", sdmc_tsk_id); #else - OS_WakeupThreadDirect( &sdmc_tsk); +// OS_WakeupThreadDirect( &sdmc_tsk); + OS_WakeupThread( &sdmc_tsk_q); #endif } @@ -1707,12 +1725,13 @@ static u16 i_sdmcSendSCR(void) #if SCR thread_flag = TRUE; SD_SendSCR(); /* SCRの取得コマンド発行 */ - PRINTDEBUG( "----- Sleep Thread -----\n"); - //can_wup( 0); + PRINTDEBUG( "--Slp Tsk--\n"); #if (TARGET_OS_CTR == 1) + //can_wup( 0); slp_tsk(); #else - OS_SleepThread( NULL); +// OS_SleepThread( NULL); + OS_SleepThread( &sdmc_tsk_q); #endif PRINTDEBUG( "waked\n"); thread_flag = FALSE; @@ -1863,12 +1882,13 @@ static u16 SDCARD_SD_Status(void) thread_flag = TRUE; SD_SDStatus(); /* ACMD13 SD_STATUSの取得コマンド発行処理 */ - PRINTDEBUG( "----- Sleep Thread -----\n"); + PRINTDEBUG( "--Slp Tsk--\n"); #if (TARGET_OS_CTR == 1) //can_wup( 0); slp_tsk(); #else - OS_SleepThread( NULL); +// OS_SleepThread( NULL); + OS_SleepThread( &sdmc_tsk_q); #endif PRINTDEBUG( "waked\n"); thread_flag = FALSE; @@ -2332,12 +2352,13 @@ static u16 i_sdmcGetResid(u32 *pResid) /*--- ACMD22 ライト済みセクタ数取得コマンド発行 ---*/ SD_SendNumWRSectors(); /*-------------------------------------------------*/ - PRINTDEBUG( "----- Sleep Thread -----\n"); + PRINTDEBUG( "--Slp Tsk--\n"); #if (TARGET_OS_CTR == 1) // can_wup( 0); slp_tsk(); #else - OS_SleepThread( NULL); +// OS_SleepThread( NULL); + OS_SleepThread( &sdmc_tsk_q); #endif PRINTDEBUG( "waked\n"); thread_flag = FALSE; @@ -2544,6 +2565,7 @@ static void SDCARD_Thread( void* arg) while( TRUE) { /* メッセージ待ち */ + PRINTDEBUG( "rcv mes sdThread\n"); #if (TARGET_OS_CTR == 1) rcv_dtq( sdmc_dtq_id, (VP_INT*)¤t_dat); #else @@ -2609,18 +2631,25 @@ static void SDCARD_Thread( void* arg) *---------------------------------------------------------------------------*/ static void SDCARD_Intr_Thread( void* arg) { - u16 sd_info1;//, sd_info2; + u16 sd_info1;//, sd_info2; + OSIntrMode enabled; while( 1) { + PRINTDEBUG( "next_tsk:0x%x\n", OS_SelectThread()); + PRINTDEBUG( "Slp sdIntr\n"); #if (TARGET_OS_CTR == 1) slp_tsk(); #else - OS_SleepThread( NULL); + OS_WaitIrq( FALSE, OS_IE_SD); + enabled = OS_DisableInterrupts(); + (void)OS_ClearIrqCheckFlag( OS_IE_SD); + (void)OS_RestoreInterrupts( enabled); + //TODO! OS_SleepThread( NULL); #endif - PRINTDEBUG( "sdmc interrupt handler : \n"); + PRINTDEBUG( "sdIntr waked\n"); /*SD割り込みのIF解除*/ - *(vu32*)CTR_INT_IF = CTR_IE_SD_MASK; + *(vu16*)CTR_INT_IF = CTR_IE_SD_MASK; /*--- FIFOを使うとき ---*/ if( SDCARD_UseFifoFlag) { @@ -2628,7 +2657,7 @@ static void SDCARD_Intr_Thread( void* arg) if( ((*SDIF_CNT & SDIF_CNT_FULL)&&(*SDIF_CNT & SDIF_CNT_FFIE)) || ((!(*SDIF_CNT & SDIF_CNT_NEMP))&&(*SDIF_CNT & SDIF_CNT_FEIE))) { - PRINTDEBUG( ">>>>> SD Interrupt (FIFO Full or Empty)\n"); + PRINTDEBUG( ">>>SD Intr(FIFO)\n");// Full or Empty)\n"); #if (TARGET_OS_CTR == 1) osDisableInterruptID( OS_INTR_ID_SD); #else @@ -2654,18 +2683,19 @@ static void SDCARD_Intr_Thread( void* arg) OS_EnableIrqMask( OS_IE_SD); #endif if( thread_flag) { - PRINTDEBUG( "----- Wakeup Thread! -----\n"); + PRINTDEBUG( "--Wup sdThread!--\n"); #if (TARGET_OS_CTR == 1) wup_tsk( sdmc_tsk_id); PRINTDEBUG( "id : 0x%x\n", sdmc_tsk_id); #else - OS_WakeupThreadDirect( &sdmc_tsk); +// OS_WakeupThreadDirect( &sdmc_tsk); + OS_WakeupThread( &sdmc_tsk_q); #endif } } }else{ if( SD_CheckFPGAReg( SD_INFO2, (SD_INFO2_MASK_BRE | SD_INFO2_MASK_BWE))) { - PRINTDEBUG( ">>>>> SD Interrupt (R/W Request from CARD)\n"); + PRINTDEBUG( ">>>SD Intr(R/W Req)\n"); //ここで自動的にラッパーのFIFO<->SD_BUF0間で通信が行われる // if((!(*SDIF_CNT & SDIF_CNT_NEMP))&&(*SDIF_CNT & SDIF_CNT_FEIE)) { #if (TARGET_OS_CTR == 1) @@ -2673,14 +2703,16 @@ static void SDCARD_Intr_Thread( void* arg) #else OS_DisableIrqMask( OS_IE_SD); #endif + PRINTDEBUG( "begin\n"); SDCARD_FPGA_irq(); + PRINTDEBUG( "end\n"); #if (TARGET_OS_CTR == 1) osEnableInterruptID( OS_INTR_ID_SD); #else OS_EnableIrqMask( OS_IE_SD); #endif }else{ - PRINTDEBUG( ">>>>> SD Interrupt (End or Err)\n"); + PRINTDEBUG( ">>>SD Intr(End or Err)\n"); #if (TARGET_OS_CTR == 1) osDisableInterruptID( OS_INTR_ID_SD); #else @@ -2694,12 +2726,13 @@ static void SDCARD_Intr_Thread( void* arg) #endif /**/ if( thread_flag) { - PRINTDEBUG( "----- Wakeup Thread -----\n"); + PRINTDEBUG( "--Wup sdThread!--\n"); #if (TARGET_OS_CTR == 1) wup_tsk( sdmc_tsk_id); PRINTDEBUG( "id : 0x%x\n", sdmc_tsk_id); #else - OS_WakeupThreadDirect( &sdmc_tsk); +// OS_WakeupThreadDirect( &sdmc_tsk); + OS_WakeupThread( &sdmc_tsk_q); #endif } } @@ -2707,20 +2740,22 @@ static void SDCARD_Intr_Thread( void* arg) /*--- FIFOを使わないとき ---*/ }else{ if( SD_CheckFPGAReg( SD_INFO2, (SD_INFO2_MASK_BRE | SD_INFO2_MASK_BWE))) { - PRINTDEBUG( ">>>>> SD Interrupt (R/W Request from CARD)\n"); + PRINTDEBUG( ">>>SD Intr(R/W Req)\n"); #if (TARGET_OS_CTR == 1) osDisableInterruptID( OS_INTR_ID_SD); #else OS_DisableIrqMask( OS_IE_SD); #endif + PRINTDEBUG( "begin\n"); SDCARD_FPGA_irq(); /*カードからのリードライト要求割り込み*/ + PRINTDEBUG( "end\n"); #if (TARGET_OS_CTR == 1) osEnableInterruptID( OS_INTR_ID_SD); #else OS_EnableIrqMask( OS_IE_SD); #endif }else{ - PRINTDEBUG( ">>>>> SD Interrupt (End or Err)\n"); + PRINTDEBUG( ">>>SD Intr(End or Err)\n"); #if (TARGET_OS_CTR == 1) osDisableInterruptID( OS_INTR_ID_SD); #else @@ -2734,12 +2769,13 @@ static void SDCARD_Intr_Thread( void* arg) #endif /**/ if( thread_flag) { - PRINTDEBUG( "----- Wakeup Thread -----\n"); + PRINTDEBUG( "--Wup sdThread!--\n"); #if (TARGET_OS_CTR == 1) wup_tsk( sdmc_tsk_id); PRINTDEBUG( "id : 0x%x\n", sdmc_tsk_id); #else - OS_WakeupThreadDirect( &sdmc_tsk); +// OS_WakeupThreadDirect( &sdmc_tsk); + OS_WakeupThread( &sdmc_tsk_q); #endif } } diff --git a/build/libraries/fatfs/ARM7/Makefile b/build/libraries/fatfs/ARM7/Makefile index 9f6a71e..a2d1486 100644 --- a/build/libraries/fatfs/ARM7/Makefile +++ b/build/libraries/fatfs/ARM7/Makefile @@ -30,7 +30,6 @@ SRCDIR = ../common/src src INCDIR = ../common INCDIR += . \ - $(TWLSDK_ROOT)/include/twl/ARM7 \ $(TWLSDK_ROOT)/include/twl/fatfs/ARM7 \ SRCS = apistat.c prfsapi.c rtlowl.c apickdsk.c apiwrite.c \ diff --git a/build/tests/fatfs/Makefile b/build/tests/fatfs/Makefile new file mode 100644 index 0000000..013c8ff --- /dev/null +++ b/build/tests/fatfs/Makefile @@ -0,0 +1,31 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: TwlSDK - tests - camera +# File: Makefile +# +# Copyright 2007 Nintendo. All rights reserved. +# +# These coded instructions, statements, and computer programs contain +# proprietary information of Nintendo of America Inc. and/or Nintendo +# Company Ltd., and are protected by Federal copyright law. They may +# not be disclosed to third parties or copied or duplicated in any form, +# in whole or in part, without the prior written consent of Nintendo. +# +# $Log: $ +# $NoKeywords: $ +#---------------------------------------------------------------------------- + +include $(TWLSDK_ROOT)/build/buildtools/commondefs + + +#---------------------------------------------------------------------------- + +SUBDIRS = fatfs_sd + + +#---------------------------------------------------------------------------- + +include $(TWLSDK_ROOT)/build/buildtools/modulerules + + +#===== End of Makefile ===== diff --git a/build/tests/fatfs/fatfs_sd/ARM7/Makefile b/build/tests/fatfs/fatfs_sd/ARM7/Makefile new file mode 100644 index 0000000..dee4706 --- /dev/null +++ b/build/tests/fatfs/fatfs_sd/ARM7/Makefile @@ -0,0 +1,53 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: TwlSDK - CAMERA - demos - camera-1 +# File: Makefile +# +# Copyright 2007 Nintendo. All rights reserved. +# +# These coded instructions, statements, and computer programs contain +# proprietary information of Nintendo of America Inc. and/or Nintendo +# Company Ltd., and are protected by Federal copyright law. They may +# not be disclosed to third parties or copied or duplicated in any form, +# in whole or in part, without the prior written consent of Nintendo. +# +# $Log: $ +# $NoKeywords: $ +#---------------------------------------------------------------------------- + +SUBDIRS = + +LCFILE_SPEC = main.lsf + +#---------------------------------------------------------------------------- + +#TWL_CODEGEN = THUMB +TWL_PROC = ARM7 + +TARGET_BIN = main.axf + +SRCS = main.c + +INCDIR += $(TWLSDK_ROOT)/include/twl \ + $(TWLSDK_ROOT)/include/twl/devices/sdmc/ARM7 \ + $(TWLSDK_ROOT)/include/twl/fatfs/ARM7 \ + +LLIBRARY_DIRS = $(TWLSDK_ROOT)/lib/ARM-BB/Release +LLIBRARIES = libfatfs_sp.twl.a \ + libromsd_sp.twl.a \ + +#SRCDIR = # using default +#LCFILE = # using default + +include $(TWLSDK_ROOT)/build/buildtools/commondefs + + +#---------------------------------------------------------------------------- + +do-build: $(TARGETS) + + +include $(TWLSDK_ROOT)/build/buildtools/modulerules + + +#===== End of Makefile ===== diff --git a/build/tests/fatfs/fatfs_sd/ARM7/main.lsf b/build/tests/fatfs/fatfs_sd/ARM7/main.lsf new file mode 100644 index 0000000..9eac241 --- /dev/null +++ b/build/tests/fatfs/fatfs_sd/ARM7/main.lsf @@ -0,0 +1,40 @@ +#---------------------------------------------------------------------------- +# Project: TwlSDK - include +# File: ARM7-BB.lsf +# +# Copyright 2007 Nintendo. All rights reserved. +# +# These coded insructions, statements, and computer programs contain +# proprietary information of Nintendo of America Inc. and/or Nintendo +# Company Ltd., and are protected by Federal copyright law. They may +# not be disclosed to third parties or copied or duplicated in any form, +# in whole or in part, without the prior written consent of Nintendo. +# +# $Log: $ +# $NoKeywords: $ +#---------------------------------------------------------------------------- +# +# Nitro LCF SPEC FILE +# + +Static $(TARGET_NAME) +{ + Address 0x02004000 + Library crt0.o + StackSize 1024 512 +} + +#Objects on MAIN RAM # nothing for elf2bin +#Autoload MAIN +#{ +# Address 0x027e0000 +# Library +#} + +Autoload MAIN +{ + Address 0x02020000 + Object $(OBJS_STATIC) + Library $(LLIBS) $(GLIBS) $(CW_LIBS) + Object * (.wram) +} diff --git a/build/tests/fatfs/fatfs_sd/ARM7/src/main.c b/build/tests/fatfs/fatfs_sd/ARM7/src/main.c new file mode 100644 index 0000000..a897928 --- /dev/null +++ b/build/tests/fatfs/fatfs_sd/ARM7/src/main.c @@ -0,0 +1,239 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - tests - snd - channel + File: main.c + + Copyright 2007 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Log: main.c,v $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ + +#include +#include +#include + +/*---------------------------------------------------------------------------* + 定数定義 + *---------------------------------------------------------------------------*/ +#define PRINTDEBUG OS_TPrintf + +/*---------------------------------------------------------------------------* + 内部関数定義 + *---------------------------------------------------------------------------*/ +static OSHeapHandle InitializeAllocateSystem(void); +static void VBlankIntr(void); + +/*---------------------------------------------------------------------------* + + *---------------------------------------------------------------------------*/ +u32 BlockBuf[512/4]; +u32 BlockBuf2[512/4]; + + +/*---------------------------------------------------------------------------* + Name: TwlSpMain + + Description: Initialize and do main + + Arguments: None. + + Returns: None. + *---------------------------------------------------------------------------*/ +void TwlSpMain(void) +{ + OSHeapHandle heapHandle; + SDMC_ERR_CODE result; + SdmcResultInfo SdResult; + + // OS初期化 + OS_Init(); + + OS_InitTick(); + OS_InitAlarm(); + + OS_InitThread(); + + // PXI初期化、ARM9と同期 + PXI_Init(); + + // ヒープ領域設定 + heapHandle = InitializeAllocateSystem(); + + + // ボタン入力サーチ初期化 + (void)PAD_InitXYButton(); + + // 割込み許可 + (void)OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr); + (void)OS_EnableIrqMask(OS_IE_V_BLANK); + (void)GX_VBlankIntr(TRUE); + (void)OS_EnableIrq(); + (void)OS_EnableInterrupts(); + + + /**/ + PRINTDEBUG("Sample program starts.\n"); +// rtfs_init(); + + /*SDドライバ初期化*/ + result = sdmcInit( NULL, NULL); + if( result != 0) { + PRINTDEBUG( "sdmcInit : failed\n"); + while( 1) {}; + }else{ + PRINTDEBUG( "sdmcInit : success\n"); + } + + /*SDからブロックリード*/ + result = sdmcReadFifo( BlockBuf, 1, 0, NULL, &SdResult); + if( result != 0) { + PRINTDEBUG( "sdmcReadFifo failed.\n"); + } + PRINTDEBUG( "sdmcReadFifo success.\n"); + + + /*SDへブロックライト*/ + MI_CpuFill8( BlockBuf2, 0xA5, 512); + result = sdmcWriteFifo( BlockBuf2, 1, 0, NULL, &SdResult); + if( result != 0) { + PRINTDEBUG( "sdmcWriteFifo failed.\n"); + } + PRINTDEBUG( "sdmcWriteFifo success.\n"); + + + /*SDからブロックリード*/ + result = sdmcReadFifo( BlockBuf2, 1, 0, NULL, &SdResult); + if( result != 0) { + PRINTDEBUG( "sdmcReadFifo failed.\n"); + } + PRINTDEBUG( "sdmcReadFifo success.\n"); + + + /*SDへブロックライト*/ + result = sdmcWriteFifo( BlockBuf, 1, 0, NULL, &SdResult); + if( result != 0) { + PRINTDEBUG( "sdmcWriteFifo failed.\n"); + } + PRINTDEBUG( "sdmcWriteFifo success.\n"); + + /*デバイスドライバの登録*/ +/* if( sdmcRtfsAttach( 4) == FALSE) { //sdmcをEドライブにする + PRINTDEBUG( "sdmcRtfsAttach failed.\n"); + }else{ + if( sdmcRtfsAttach( 4) == FALSE) { + PRINTDEBUG( "sdmcRtfsAttach success.\n"); + }else{ + PRINTDEBUG( "sdmcRtfsAttach error!.\n"); + } + } + + if( !rtfs_pc_set_default_drive( (unsigned char*)"E:")) { + PRINTDEBUG( "pc_set_default_drive failed\n"); + while( 1){}; + } + PRINTDEBUG( "pc_set_default_drive success\n");*/ + + PRINTDEBUG( "Sample program ends.\n"); + + + while (TRUE) + { + OS_Halt(); + + //---- check reset + if (OS_IsResetOccurred()) + { + OS_ResetSystem(); + } + } +} + +/*---------------------------------------------------------------------------* + Name: InitializeAllocateSystem + + Description: メモリ割当てシステムを初期化する。 + + Arguments: None. + + Returns: None. + *---------------------------------------------------------------------------*/ +static OSHeapHandle InitializeAllocateSystem(void) +{ + void *tempLo; + OSHeapHandle hh; + + OS_TPrintf("OS_GetWramSubPrivArenaLo() = %p\n", OS_GetWramSubPrivArenaLo()); + OS_TPrintf("OS_GetWramSubPrivArenaHi() = %p\n", OS_GetWramSubPrivArenaHi()); + OS_TPrintf("OS_GetWramSubArenaLo() = %p\n", OS_GetWramSubArenaLo()); + OS_TPrintf("OS_GetWramSubArenaHi() = %p\n", OS_GetWramSubArenaHi()); + OS_TPrintf("OS_GetSubPrivArenaLo() = %p\n", OS_GetSubPrivArenaLo()); + OS_TPrintf("OS_GetSubPrivArenaHi() = %p\n", OS_GetSubPrivArenaHi()); + + OS_TPrintf("call OS_SetWramSubPrivArenaHi(0x0380f980); to fix arena.\n"); + OS_SetWramSubPrivArenaHi((void*)0x0380f980); + + // メモリ割当て初期化 + tempLo = OS_InitAlloc(OS_ARENA_WRAM_SUBPRIV, + OS_GetWramSubPrivArenaLo(), OS_GetWramSubPrivArenaHi(), 1); + + // アリーナを0クリア + MI_CpuClear8(tempLo, (u32)OS_GetWramSubPrivArenaHi() - (u32)tempLo); + + // アリーナ下位アドレスを設定 + OS_SetArenaLo(OS_ARENA_WRAM_SUBPRIV, tempLo); + + // ヒープ作成 + hh = OS_CreateHeap(OS_ARENA_WRAM_SUBPRIV, + OS_GetWramSubPrivArenaLo(), OS_GetWramSubPrivArenaHi()); + + if (hh < 0) + { + OS_Panic("ARM7: Fail to create heap.\n"); + } + + // カレントヒープに設定 + (void)OS_SetCurrentHeap(OS_ARENA_WRAM_SUBPRIV, hh); + + return hh; +} + +/*---------------------------------------------------------------------------* + Name: VBlankIntr + + Description: VBlank interrupt handler + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +#ifndef SDK_TEG + +extern BOOL PMi_Initialized; +void PM_SelfBlinkProc(void); + +static void VBlankIntr(void) +{ + //---- LED blink system + if (PMi_Initialized) + { + PM_SelfBlinkProc(); + } +} + +#else + +static void VBlankIntr(void) +{ +} + +#endif + +/*---------------------------------------------------------------------------* + End of file + *---------------------------------------------------------------------------*/ diff --git a/build/tests/fatfs/fatfs_sd/Makefile b/build/tests/fatfs/fatfs_sd/Makefile new file mode 100644 index 0000000..078ec37 --- /dev/null +++ b/build/tests/fatfs/fatfs_sd/Makefile @@ -0,0 +1,32 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: TwlSDK - build +# File: Makefile +# +# Copyright 2007 Nintendo. All rights reserved. +# +# These coded instructions, statements, and computer programs contain +# proprietary information of Nintendo of America Inc. and/or Nintendo +# Company Ltd., and are protected by Federal copyright law. They may +# not be disclosed to third parties or copied or duplicated in any form, +# in whole or in part, without the prior written consent of Nintendo. +# +# $Log: $ +# $NoKeywords: $ +#---------------------------------------------------------------------------- + +include $(TWLSDK_ROOT)/build/buildtools/commondefs + + +#---------------------------------------------------------------------------- + +SUBDIRS = \ + ARM7 \ + ARM9 \ + +#---------------------------------------------------------------------------- + +include $(TWLSDK_ROOT)/build/buildtools/modulerules + + +#===== End of Makefile =====